robotframework-okw4robot 0.4.0__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.
Files changed (34) hide show
  1. robotframework_okw4robot-0.4.0/LICENSE +36 -0
  2. robotframework_okw4robot-0.4.0/PKG-INFO +275 -0
  3. robotframework_okw4robot-0.4.0/README.md +208 -0
  4. robotframework_okw4robot-0.4.0/pyproject.toml +50 -0
  5. robotframework_okw4robot-0.4.0/setup.cfg +4 -0
  6. robotframework_okw4robot-0.4.0/src/okw4robot/__init__.py +3 -0
  7. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/__init__.py +0 -0
  8. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/app.py +37 -0
  9. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/attribute_keywords.py +54 -0
  10. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/caption_keywords.py +53 -0
  11. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/host.py +35 -0
  12. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/label_keywords.py +53 -0
  13. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/list_keywords.py +72 -0
  14. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/params.py +43 -0
  15. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/placeholder_keywords.py +53 -0
  16. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/table_keywords.py +746 -0
  17. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/tooltip_keywords.py +99 -0
  18. robotframework_okw4robot-0.4.0/src/okw4robot/keywords/widget_keywords.py +510 -0
  19. robotframework_okw4robot-0.4.0/src/okw4robot/library.py +159 -0
  20. robotframework_okw4robot-0.4.0/src/okw4robot/runtime/__init__.py +0 -0
  21. robotframework_okw4robot-0.4.0/src/okw4robot/runtime/context.py +168 -0
  22. robotframework_okw4robot-0.4.0/src/okw4robot/utils/__init__.py +0 -0
  23. robotframework_okw4robot-0.4.0/src/okw4robot/utils/loader.py +6 -0
  24. robotframework_okw4robot-0.4.0/src/okw4robot/utils/logging_mixin.py +56 -0
  25. robotframework_okw4robot-0.4.0/src/okw4robot/utils/okw_helpers.py +177 -0
  26. robotframework_okw4robot-0.4.0/src/okw4robot/utils/table_tokens.py +129 -0
  27. robotframework_okw4robot-0.4.0/src/okw4robot/utils/yaml_loader.py +59 -0
  28. robotframework_okw4robot-0.4.0/src/okw4robot/widgets/__init__.py +0 -0
  29. robotframework_okw4robot-0.4.0/src/okw4robot/widgets/okw_widget.py +144 -0
  30. robotframework_okw4robot-0.4.0/src/robotframework_okw4robot.egg-info/PKG-INFO +275 -0
  31. robotframework_okw4robot-0.4.0/src/robotframework_okw4robot.egg-info/SOURCES.txt +32 -0
  32. robotframework_okw4robot-0.4.0/src/robotframework_okw4robot.egg-info/dependency_links.txt +1 -0
  33. robotframework_okw4robot-0.4.0/src/robotframework_okw4robot.egg-info/requires.txt +6 -0
  34. robotframework_okw4robot-0.4.0/src/robotframework_okw4robot.egg-info/top_level.txt +1 -0
@@ -0,0 +1,36 @@
1
+ OKW4Robot Community License (Nicht‑kommerzielle Nutzung)
2
+
3
+ Copyright (c) 2025 Zoltán Hrabovszki
4
+
5
+ 1. Begriffe
6
+ - "Software": die Bibliothek "OKW4Robot" samt zugehöriger Quell‑ und Binärdateien.
7
+ - "Nicht‑kommerzielle Nutzung": jede Nutzung zu privaten, akademischen oder Open‑Source‑Zwecken ohne direkten oder indirekten Umsatzbezug, sowie reine Evaluierung/PoC.
8
+ - "Kommerzielle Nutzung": jede Nutzung in oder für ein Produkt, einen Service oder Prozess, der direkt oder indirekt Einnahmen generiert (z. B. bezahlte Projekte, Firmen‑CI/Tests für kommerzielle Produkte, SaaS, Resale). Für kommerzielle Nutzung ist eine gesonderte kommerzielle Lizenz erforderlich.
9
+
10
+ 2. Lizenzgewährung (nicht‑kommerziell)
11
+ Der Rechteinhaber gewährt eine weltweite, nicht‑exklusive, nicht übertragbare, unentgeltliche Lizenz zur Nutzung, Vervielfältigung, Änderung und Weitergabe der Software ausschließlich für nicht‑kommerzielle Zwecke, vorausgesetzt, dass (a) dieser Lizenztext in Kopien und abgeleiteten Werken enthalten bleibt und (b) Urheber‑ und Hinweistexte nicht entfernt werden.
12
+
13
+ 3. Einschränkungen
14
+ - Kommerzielle Nutzung ist ohne kommerzielle Lizenz untersagt.
15
+ - Marken‑ und Namensrechte werden nicht gewährt.
16
+ - Sublicensing ist nur unter Beibehaltung dieser Bedingungen zulässig.
17
+
18
+ 4. Support
19
+ Es besteht kein Anspruch auf Wartung, Support oder Updates.
20
+
21
+ 5. Gewährleistungsausschluss
22
+ Die Software wird "wie besehen" ("AS IS") bereitgestellt, ohne ausdrückliche oder stillschweigende Gewährleistung. Insbesondere wird keine Gewähr für Marktgängigkeit, Eignung für einen bestimmten Zweck, Nichtverletzung von Rechten Dritter, Fehlerfreiheit, Richtigkeit oder Verfügbarkeit übernommen.
23
+
24
+ 6. Haftungsbeschränkung
25
+ Soweit gesetzlich zulässig, haften der Rechteinhaber und Mitwirkende in keinem Fall für Schäden jedweder Art (einschließlich, aber nicht beschränkt auf direkte, indirekte, zufällige, besondere, exemplarische oder Folgeschäden, entgangenen Gewinn, Produktions‑/Betriebsunterbrechung, Datenverlust oder Rechtsverfolgungskosten), die aus der Nutzung, Unmöglichkeit der Nutzung oder Leistung der Software entstehen, selbst wenn auf die Möglichkeit solcher Schäden hingewiesen wurde.
26
+
27
+ Unberührt bleiben zwingende Haftungstatbestände (z. B. nach dem Produkthaftungsgesetz) sowie die Haftung für Vorsatz, grobe Fahrlässigkeit oder für Verletzungen von Leben, Körper oder Gesundheit nach geltendem Recht.
28
+
29
+ 7. Laufzeit und Beendigung
30
+ Diese Lizenz gilt bis zu ihrer Beendigung. Bei Verstoß erlischt das Nutzungsrecht automatisch; die Nutzung ist einzustellen. Rechte an bereits rechtmäßig weitergegebenen Kopien bleiben unberührt.
31
+
32
+ 8. Sonstiges
33
+ Es gilt materielles Recht des Sitzstaats des Rechteinhabers unter Ausschluss des Kollisionsrechts. Sollte eine Bestimmung unwirksam sein, bleibt der Rest wirksam (Salvatorische Klausel).
34
+
35
+ Kommerzielle Lizenz
36
+ Für eine kommerzielle Nutzung (siehe Abschnitt 1) wenden Sie sich bitte an den Rechteinhaber, um Konditionen und Gebühren zu vereinbaren.
@@ -0,0 +1,275 @@
1
+ Metadata-Version: 2.4
2
+ Name: robotframework-okw4robot
3
+ Version: 0.4.0
4
+ Summary: Driver-agnostic Robot Framework keyword library core for GUI test automation (OKW4Robot).
5
+ Author: Zoltán Hrabovszki
6
+ License: OKW4Robot Community License (Nicht‑kommerzielle Nutzung)
7
+
8
+ Copyright (c) 2025 Zoltán Hrabovszki
9
+
10
+ 1. Begriffe
11
+ - "Software": die Bibliothek "OKW4Robot" samt zugehöriger Quell‑ und Binärdateien.
12
+ - "Nicht‑kommerzielle Nutzung": jede Nutzung zu privaten, akademischen oder Open‑Source‑Zwecken ohne direkten oder indirekten Umsatzbezug, sowie reine Evaluierung/PoC.
13
+ - "Kommerzielle Nutzung": jede Nutzung in oder für ein Produkt, einen Service oder Prozess, der direkt oder indirekt Einnahmen generiert (z. B. bezahlte Projekte, Firmen‑CI/Tests für kommerzielle Produkte, SaaS, Resale). Für kommerzielle Nutzung ist eine gesonderte kommerzielle Lizenz erforderlich.
14
+
15
+ 2. Lizenzgewährung (nicht‑kommerziell)
16
+ Der Rechteinhaber gewährt eine weltweite, nicht‑exklusive, nicht übertragbare, unentgeltliche Lizenz zur Nutzung, Vervielfältigung, Änderung und Weitergabe der Software ausschließlich für nicht‑kommerzielle Zwecke, vorausgesetzt, dass (a) dieser Lizenztext in Kopien und abgeleiteten Werken enthalten bleibt und (b) Urheber‑ und Hinweistexte nicht entfernt werden.
17
+
18
+ 3. Einschränkungen
19
+ - Kommerzielle Nutzung ist ohne kommerzielle Lizenz untersagt.
20
+ - Marken‑ und Namensrechte werden nicht gewährt.
21
+ - Sublicensing ist nur unter Beibehaltung dieser Bedingungen zulässig.
22
+
23
+ 4. Support
24
+ Es besteht kein Anspruch auf Wartung, Support oder Updates.
25
+
26
+ 5. Gewährleistungsausschluss
27
+ Die Software wird "wie besehen" ("AS IS") bereitgestellt, ohne ausdrückliche oder stillschweigende Gewährleistung. Insbesondere wird keine Gewähr für Marktgängigkeit, Eignung für einen bestimmten Zweck, Nichtverletzung von Rechten Dritter, Fehlerfreiheit, Richtigkeit oder Verfügbarkeit übernommen.
28
+
29
+ 6. Haftungsbeschränkung
30
+ Soweit gesetzlich zulässig, haften der Rechteinhaber und Mitwirkende in keinem Fall für Schäden jedweder Art (einschließlich, aber nicht beschränkt auf direkte, indirekte, zufällige, besondere, exemplarische oder Folgeschäden, entgangenen Gewinn, Produktions‑/Betriebsunterbrechung, Datenverlust oder Rechtsverfolgungskosten), die aus der Nutzung, Unmöglichkeit der Nutzung oder Leistung der Software entstehen, selbst wenn auf die Möglichkeit solcher Schäden hingewiesen wurde.
31
+
32
+ Unberührt bleiben zwingende Haftungstatbestände (z. B. nach dem Produkthaftungsgesetz) sowie die Haftung für Vorsatz, grobe Fahrlässigkeit oder für Verletzungen von Leben, Körper oder Gesundheit nach geltendem Recht.
33
+
34
+ 7. Laufzeit und Beendigung
35
+ Diese Lizenz gilt bis zu ihrer Beendigung. Bei Verstoß erlischt das Nutzungsrecht automatisch; die Nutzung ist einzustellen. Rechte an bereits rechtmäßig weitergegebenen Kopien bleiben unberührt.
36
+
37
+ 8. Sonstiges
38
+ Es gilt materielles Recht des Sitzstaats des Rechteinhabers unter Ausschluss des Kollisionsrechts. Sollte eine Bestimmung unwirksam sein, bleibt der Rest wirksam (Salvatorische Klausel).
39
+
40
+ Kommerzielle Lizenz
41
+ Für eine kommerzielle Nutzung (siehe Abschnitt 1) wenden Sie sich bitte an den Rechteinhaber, um Konditionen und Gebühren zu vereinbaren.
42
+
43
+ Project-URL: Repository, https://github.com/Hrabovszki1023/robotframework-okw4robot
44
+ Project-URL: Homepage, https://github.com/Hrabovszki1023/robotframework-okw4robot
45
+ Project-URL: Documentation, https://hrabovszki1023.github.io/robotframework-okw4robot/
46
+ Keywords: robotframework,testing,testautomation,gui,okw,okw4robot
47
+ Classifier: Development Status :: 4 - Beta
48
+ Classifier: Operating System :: OS Independent
49
+ Classifier: Programming Language :: Python :: 3
50
+ Classifier: Programming Language :: Python :: 3 :: Only
51
+ Classifier: Programming Language :: Python :: 3.10
52
+ Classifier: Programming Language :: Python :: 3.11
53
+ Classifier: Programming Language :: Python :: 3.12
54
+ Classifier: Programming Language :: Python :: 3.13
55
+ Classifier: Framework :: Robot Framework
56
+ Classifier: Framework :: Robot Framework :: Library
57
+ Classifier: Topic :: Software Development :: Testing
58
+ Requires-Python: >=3.10
59
+ Description-Content-Type: text/markdown
60
+ License-File: LICENSE
61
+ Requires-Dist: robotframework>=6.0
62
+ Requires-Dist: PyYAML>=6.0
63
+ Requires-Dist: okw-contract-utils>=0.2.0
64
+ Provides-Extra: dev
65
+ Requires-Dist: pytest>=7.0; extra == "dev"
66
+ Dynamic: license-file
67
+
68
+ # OKW4Robot
69
+
70
+ Driver-agnostic keyword architecture for [Robot Framework](https://robotframework.org/).
71
+
72
+ One unified set of keywords for different GUI technologies
73
+ (Web/Selenium, Web/Playwright, Java Swing, ...) — the actual implementation
74
+ lives in the respective driver package.
75
+
76
+ > **Deutsche Version:** [README_de.md](README_de.md)
77
+
78
+ ---
79
+
80
+ ## OKW Ecosystem
81
+
82
+ ```
83
+ ┌─────────────────────────────────────────────────────────┐
84
+ │ Robot Tests (.robot) │
85
+ │ StartHost Chrome / SetValue Name "Smith" │
86
+ └──────────────────────────┬──────────────────────────────┘
87
+
88
+ ┌───────────▼───────────┐
89
+ │ okw4robot │ Driver-agnostic core
90
+ │ Keywords, OkwWidget │ pip install robotframework-okw4robot
91
+ │ Context, Contracts │
92
+ └───┬───────────────┬───┘
93
+ │ │
94
+ ┌──────────▼──┐ ┌─────▼──────────┐
95
+ │ okw-web- │ │ okw-java- │ (more drivers
96
+ │ selenium │ │ swing │ e.g. okw-web-
97
+ │ WebSe_* │ │ JavaSw_* │ playwright)
98
+ └─────────────┘ └────────────────┘
99
+ ```
100
+
101
+ | Package | Namespace | Status | Description |
102
+ |---------|-----------|--------|-------------|
103
+ | **okw4robot** | `okw4robot` | Stable | Core: keywords, OkwWidget interface, context, contracts |
104
+ | **okw-web-selenium** | `okw_web_selenium` | Stable (53 tests) | Selenium WebDriver + WebSe_* widgets |
105
+ | **okw-java-swing** | `okw_java_swing` | WIP | Java Swing via JSON-RPC |
106
+ | **okw-contract-utils** | `okw_contract_utils` | Stable (PyPI) | Shared contracts (matchers, tokens, YES/NO) |
107
+ | **okw-remote-ssh** | `robotframework_okw_remote_ssh` | Beta (PyPI) | SSH commands and SFTP |
108
+
109
+ ---
110
+
111
+ ## Getting Started
112
+
113
+ ### 1. Install the core
114
+
115
+ ```bash
116
+ pip install robotframework-okw4robot
117
+ ```
118
+
119
+ ### 2. Install a driver package (e.g. Selenium)
120
+
121
+ ```bash
122
+ pip install robotframework-okw-web-selenium
123
+ ```
124
+
125
+ ### 3. Write a Robot test
126
+
127
+ ```robotframework
128
+ *** Settings ***
129
+ Library okw_web_selenium.library.OkwWebSeleniumLibrary
130
+
131
+ *** Test Cases ***
132
+ Login Test
133
+ StartHost Chrome
134
+ StartApp Chrome
135
+ SelectWindow Chrome
136
+ SetValue URL https://example.com/login
137
+ StartApp MyApp
138
+ SelectWindow LoginDialog
139
+ SetValue Username admin
140
+ SetValue Password secret
141
+ ClickOn Login
142
+ VerifyValue Status Logged in
143
+ StopHost
144
+ ```
145
+
146
+ > **Note:** The test imports the *driver library* (`OkwWebSeleniumLibrary`),
147
+ > not `OKW4RobotLibrary` directly. The driver library inherits all keywords
148
+ > from the core.
149
+
150
+ ---
151
+
152
+ ## Architecture: Delegation, Not Control
153
+
154
+ Keywords do not call adapter methods directly. Instead, they delegate to
155
+ exactly **one** `okw_*` method on the widget:
156
+
157
+ ```
158
+ Keyword SetValue "Name" "Smith"
159
+
160
+
161
+ widget = resolve_widget("Name") # YAML locator → WebSe_TextField
162
+ widget.okw_set_value("Smith") # Widget knows how.
163
+ ```
164
+
165
+ The `OkwWidget` interface (in `okw4robot`) defines all `okw_*` methods
166
+ with `NotImplementedError`. Driver packages implement them:
167
+
168
+ | okw4robot (Interface) | okw-web-selenium (Implementation) |
169
+ |-----------------------|-----------------------------------|
170
+ | `OkwWidget.okw_set_value()` | `WebSe_TextField.okw_set_value()` → Selenium `clear` + `input_text` |
171
+ | `OkwWidget.okw_click()` | `WebSe_Base.okw_click()` → Selenium `click_element` |
172
+ | `OkwWidget.okw_exists()` | `WebSe_Base.okw_exists()` → Selenium `find_elements` |
173
+
174
+ ---
175
+
176
+ ## Project Structure
177
+
178
+ ```
179
+ robotframework-okw4robot/
180
+ src/okw4robot/
181
+ library.py # OKW4RobotLibrary (all keyword mixins)
182
+ keywords/
183
+ host.py # StartHost, StopHost, SelectHost
184
+ app.py # StartApp, StopApp, SelectWindow
185
+ widget_keywords.py # SetValue, ClickOn, VerifyValue, ...
186
+ attribute_keywords.py # VerifyAttribute, MemorizeAttribute, LogAttribute
187
+ caption_keywords.py # VerifyCaption, MemorizeCaption, LogCaption
188
+ label_keywords.py # VerifyLabel, MemorizeLabel, LogLabel
189
+ placeholder_keywords.py # VerifyPlaceholder, ...
190
+ tooltip_keywords.py # VerifyTooltip, ...
191
+ table_keywords.py # VerifyTableCellValue, ...
192
+ list_keywords.py # VerifyListCount, VerifySelectedCount
193
+ params.py # SetOKWParameter (timeouts)
194
+ runtime/
195
+ context.py # Central runtime context (adapter, app, window)
196
+ widgets/
197
+ okw_widget.py # OkwWidget interface (NotImplementedError defaults)
198
+ utils/
199
+ yaml_loader.py # YAML locator search (project → driver packages)
200
+ loader.py # Dynamic class loading
201
+ okw_helpers.py # resolve_widget(), should_ignore(), ...
202
+ logging_mixin.py # LoggingMixin for all classes
203
+ table_tokens.py # $TAB/$LF token parser
204
+ tests/
205
+ unit/ # 53 pytest unit tests with MockWidget
206
+ docs/
207
+ CONTRACT.md # Public contract
208
+ KEYWORDS.md # Keyword reference (all keywords)
209
+ SPECIFICATION.md # Semantic specification
210
+ keywords_*.md # Keyword documentation per topic
211
+ okw_parameters.md # Timeouts and parameters
212
+ synchronization_strategy.md # Sync strategy (wait_before)
213
+ ...
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Documentation
219
+
220
+ ### Contracts and Specification
221
+
222
+ - [CONTRACT.md](docs/CONTRACT.md) – Public contract (architecture, YAML fallback)
223
+ - [KEYWORDS.md](docs/KEYWORDS.md) – Keyword reference (all keywords at a glance)
224
+ - [SPECIFICATION.md](docs/SPECIFICATION.md) – Semantic keyword specification
225
+
226
+ ### Keywords
227
+
228
+ - [keywords_host_app.md](docs/keywords_host_app.md) – Host/App/Window keywords
229
+ - [keywords_attribute.md](docs/keywords_attribute.md) – VerifyAttribute, MemorizeAttribute, LogAttribute
230
+ - [keywords_caption.md](docs/keywords_caption.md) – VerifyCaption, MemorizeCaption, LogCaption
231
+ - [keywords_label.md](docs/keywords_label.md) – VerifyLabel, MemorizeLabel, LogLabel
232
+ - [keywords_placeholder.md](docs/keywords_placeholder.md) – VerifyPlaceholder, ...
233
+ - [keywords_tooltip.md](docs/keywords_tooltip.md) – VerifyTooltip, ...
234
+ - [keywords_table.md](docs/keywords_table.md) – Table keywords (index-based)
235
+ - [keywords_table_headers.md](docs/keywords_table_headers.md) – Table keywords (header-based)
236
+ - [keywords_list.md](docs/keywords_list.md) – VerifyListCount, VerifySelectedCount
237
+ - [keywords_ignore_rule.md](docs/keywords_ignore_rule.md) – $IGNORE, $EMPTY, $DELETE
238
+
239
+ ### Concepts
240
+
241
+ - [context.md](docs/context.md) – Runtime context (adapter, app, window)
242
+ - [objektzustaende.md](docs/objektzustaende.md) – Widget states (exists, visible, enabled, ...)
243
+ - [okw_parameters.md](docs/okw_parameters.md) – Timeouts and parameters ([DE](docs/okw_parameters_de.md))
244
+ - [synchronization_strategy.md](docs/synchronization_strategy.md) – Sync strategy
245
+ - [widgets_common.md](docs/widgets_common.md) – Widget hierarchy and OkwWidget interface
246
+ - [table_tokens.md](docs/table_tokens.md) – $TAB/$LF token syntax
247
+ - [regex_best_practices.md](docs/regex_best_practices.md) – Regex tips for Robot Framework
248
+
249
+ ---
250
+
251
+ ## Waiting for Values and Synchronization
252
+
253
+ Verify keywords automatically wait for expected values (with timeout and polling):
254
+
255
+ ```robotframework
256
+ # Set timeout (optional, default: 10s)
257
+ SetOKWParameter TimeOutVerifyValue 15
258
+
259
+ # Keyword waits up to 15s for the expected value
260
+ VerifyValue Status Logged in
261
+ ```
262
+
263
+ Write actions (Click, SetValue, TypeKey, Select) check preconditions first:
264
+ `exists → scroll_into_view → visible → enabled → editable → until_not_visible`
265
+
266
+ Details: [docs/okw_parameters.md](docs/okw_parameters.md),
267
+ [docs/synchronization_strategy.md](docs/synchronization_strategy.md)
268
+
269
+ ---
270
+
271
+ ## License
272
+
273
+ - **Community** (non-commercial): see [LICENSE](LICENSE)
274
+ - **Commercial**: see [COMMERCIAL_LICENSE.md](COMMERCIAL_LICENSE.md)
275
+ - **FAQ**: [docs/license_faq.md](docs/license_faq.md)
@@ -0,0 +1,208 @@
1
+ # OKW4Robot
2
+
3
+ Driver-agnostic keyword architecture for [Robot Framework](https://robotframework.org/).
4
+
5
+ One unified set of keywords for different GUI technologies
6
+ (Web/Selenium, Web/Playwright, Java Swing, ...) — the actual implementation
7
+ lives in the respective driver package.
8
+
9
+ > **Deutsche Version:** [README_de.md](README_de.md)
10
+
11
+ ---
12
+
13
+ ## OKW Ecosystem
14
+
15
+ ```
16
+ ┌─────────────────────────────────────────────────────────┐
17
+ │ Robot Tests (.robot) │
18
+ │ StartHost Chrome / SetValue Name "Smith" │
19
+ └──────────────────────────┬──────────────────────────────┘
20
+
21
+ ┌───────────▼───────────┐
22
+ │ okw4robot │ Driver-agnostic core
23
+ │ Keywords, OkwWidget │ pip install robotframework-okw4robot
24
+ │ Context, Contracts │
25
+ └───┬───────────────┬───┘
26
+ │ │
27
+ ┌──────────▼──┐ ┌─────▼──────────┐
28
+ │ okw-web- │ │ okw-java- │ (more drivers
29
+ │ selenium │ │ swing │ e.g. okw-web-
30
+ │ WebSe_* │ │ JavaSw_* │ playwright)
31
+ └─────────────┘ └────────────────┘
32
+ ```
33
+
34
+ | Package | Namespace | Status | Description |
35
+ |---------|-----------|--------|-------------|
36
+ | **okw4robot** | `okw4robot` | Stable | Core: keywords, OkwWidget interface, context, contracts |
37
+ | **okw-web-selenium** | `okw_web_selenium` | Stable (53 tests) | Selenium WebDriver + WebSe_* widgets |
38
+ | **okw-java-swing** | `okw_java_swing` | WIP | Java Swing via JSON-RPC |
39
+ | **okw-contract-utils** | `okw_contract_utils` | Stable (PyPI) | Shared contracts (matchers, tokens, YES/NO) |
40
+ | **okw-remote-ssh** | `robotframework_okw_remote_ssh` | Beta (PyPI) | SSH commands and SFTP |
41
+
42
+ ---
43
+
44
+ ## Getting Started
45
+
46
+ ### 1. Install the core
47
+
48
+ ```bash
49
+ pip install robotframework-okw4robot
50
+ ```
51
+
52
+ ### 2. Install a driver package (e.g. Selenium)
53
+
54
+ ```bash
55
+ pip install robotframework-okw-web-selenium
56
+ ```
57
+
58
+ ### 3. Write a Robot test
59
+
60
+ ```robotframework
61
+ *** Settings ***
62
+ Library okw_web_selenium.library.OkwWebSeleniumLibrary
63
+
64
+ *** Test Cases ***
65
+ Login Test
66
+ StartHost Chrome
67
+ StartApp Chrome
68
+ SelectWindow Chrome
69
+ SetValue URL https://example.com/login
70
+ StartApp MyApp
71
+ SelectWindow LoginDialog
72
+ SetValue Username admin
73
+ SetValue Password secret
74
+ ClickOn Login
75
+ VerifyValue Status Logged in
76
+ StopHost
77
+ ```
78
+
79
+ > **Note:** The test imports the *driver library* (`OkwWebSeleniumLibrary`),
80
+ > not `OKW4RobotLibrary` directly. The driver library inherits all keywords
81
+ > from the core.
82
+
83
+ ---
84
+
85
+ ## Architecture: Delegation, Not Control
86
+
87
+ Keywords do not call adapter methods directly. Instead, they delegate to
88
+ exactly **one** `okw_*` method on the widget:
89
+
90
+ ```
91
+ Keyword SetValue "Name" "Smith"
92
+
93
+
94
+ widget = resolve_widget("Name") # YAML locator → WebSe_TextField
95
+ widget.okw_set_value("Smith") # Widget knows how.
96
+ ```
97
+
98
+ The `OkwWidget` interface (in `okw4robot`) defines all `okw_*` methods
99
+ with `NotImplementedError`. Driver packages implement them:
100
+
101
+ | okw4robot (Interface) | okw-web-selenium (Implementation) |
102
+ |-----------------------|-----------------------------------|
103
+ | `OkwWidget.okw_set_value()` | `WebSe_TextField.okw_set_value()` → Selenium `clear` + `input_text` |
104
+ | `OkwWidget.okw_click()` | `WebSe_Base.okw_click()` → Selenium `click_element` |
105
+ | `OkwWidget.okw_exists()` | `WebSe_Base.okw_exists()` → Selenium `find_elements` |
106
+
107
+ ---
108
+
109
+ ## Project Structure
110
+
111
+ ```
112
+ robotframework-okw4robot/
113
+ src/okw4robot/
114
+ library.py # OKW4RobotLibrary (all keyword mixins)
115
+ keywords/
116
+ host.py # StartHost, StopHost, SelectHost
117
+ app.py # StartApp, StopApp, SelectWindow
118
+ widget_keywords.py # SetValue, ClickOn, VerifyValue, ...
119
+ attribute_keywords.py # VerifyAttribute, MemorizeAttribute, LogAttribute
120
+ caption_keywords.py # VerifyCaption, MemorizeCaption, LogCaption
121
+ label_keywords.py # VerifyLabel, MemorizeLabel, LogLabel
122
+ placeholder_keywords.py # VerifyPlaceholder, ...
123
+ tooltip_keywords.py # VerifyTooltip, ...
124
+ table_keywords.py # VerifyTableCellValue, ...
125
+ list_keywords.py # VerifyListCount, VerifySelectedCount
126
+ params.py # SetOKWParameter (timeouts)
127
+ runtime/
128
+ context.py # Central runtime context (adapter, app, window)
129
+ widgets/
130
+ okw_widget.py # OkwWidget interface (NotImplementedError defaults)
131
+ utils/
132
+ yaml_loader.py # YAML locator search (project → driver packages)
133
+ loader.py # Dynamic class loading
134
+ okw_helpers.py # resolve_widget(), should_ignore(), ...
135
+ logging_mixin.py # LoggingMixin for all classes
136
+ table_tokens.py # $TAB/$LF token parser
137
+ tests/
138
+ unit/ # 53 pytest unit tests with MockWidget
139
+ docs/
140
+ CONTRACT.md # Public contract
141
+ KEYWORDS.md # Keyword reference (all keywords)
142
+ SPECIFICATION.md # Semantic specification
143
+ keywords_*.md # Keyword documentation per topic
144
+ okw_parameters.md # Timeouts and parameters
145
+ synchronization_strategy.md # Sync strategy (wait_before)
146
+ ...
147
+ ```
148
+
149
+ ---
150
+
151
+ ## Documentation
152
+
153
+ ### Contracts and Specification
154
+
155
+ - [CONTRACT.md](docs/CONTRACT.md) – Public contract (architecture, YAML fallback)
156
+ - [KEYWORDS.md](docs/KEYWORDS.md) – Keyword reference (all keywords at a glance)
157
+ - [SPECIFICATION.md](docs/SPECIFICATION.md) – Semantic keyword specification
158
+
159
+ ### Keywords
160
+
161
+ - [keywords_host_app.md](docs/keywords_host_app.md) – Host/App/Window keywords
162
+ - [keywords_attribute.md](docs/keywords_attribute.md) – VerifyAttribute, MemorizeAttribute, LogAttribute
163
+ - [keywords_caption.md](docs/keywords_caption.md) – VerifyCaption, MemorizeCaption, LogCaption
164
+ - [keywords_label.md](docs/keywords_label.md) – VerifyLabel, MemorizeLabel, LogLabel
165
+ - [keywords_placeholder.md](docs/keywords_placeholder.md) – VerifyPlaceholder, ...
166
+ - [keywords_tooltip.md](docs/keywords_tooltip.md) – VerifyTooltip, ...
167
+ - [keywords_table.md](docs/keywords_table.md) – Table keywords (index-based)
168
+ - [keywords_table_headers.md](docs/keywords_table_headers.md) – Table keywords (header-based)
169
+ - [keywords_list.md](docs/keywords_list.md) – VerifyListCount, VerifySelectedCount
170
+ - [keywords_ignore_rule.md](docs/keywords_ignore_rule.md) – $IGNORE, $EMPTY, $DELETE
171
+
172
+ ### Concepts
173
+
174
+ - [context.md](docs/context.md) – Runtime context (adapter, app, window)
175
+ - [objektzustaende.md](docs/objektzustaende.md) – Widget states (exists, visible, enabled, ...)
176
+ - [okw_parameters.md](docs/okw_parameters.md) – Timeouts and parameters ([DE](docs/okw_parameters_de.md))
177
+ - [synchronization_strategy.md](docs/synchronization_strategy.md) – Sync strategy
178
+ - [widgets_common.md](docs/widgets_common.md) – Widget hierarchy and OkwWidget interface
179
+ - [table_tokens.md](docs/table_tokens.md) – $TAB/$LF token syntax
180
+ - [regex_best_practices.md](docs/regex_best_practices.md) – Regex tips for Robot Framework
181
+
182
+ ---
183
+
184
+ ## Waiting for Values and Synchronization
185
+
186
+ Verify keywords automatically wait for expected values (with timeout and polling):
187
+
188
+ ```robotframework
189
+ # Set timeout (optional, default: 10s)
190
+ SetOKWParameter TimeOutVerifyValue 15
191
+
192
+ # Keyword waits up to 15s for the expected value
193
+ VerifyValue Status Logged in
194
+ ```
195
+
196
+ Write actions (Click, SetValue, TypeKey, Select) check preconditions first:
197
+ `exists → scroll_into_view → visible → enabled → editable → until_not_visible`
198
+
199
+ Details: [docs/okw_parameters.md](docs/okw_parameters.md),
200
+ [docs/synchronization_strategy.md](docs/synchronization_strategy.md)
201
+
202
+ ---
203
+
204
+ ## License
205
+
206
+ - **Community** (non-commercial): see [LICENSE](LICENSE)
207
+ - **Commercial**: see [COMMERCIAL_LICENSE.md](COMMERCIAL_LICENSE.md)
208
+ - **FAQ**: [docs/license_faq.md](docs/license_faq.md)
@@ -0,0 +1,50 @@
1
+ [build-system]
2
+ requires = ["setuptools>=65", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "robotframework-okw4robot"
7
+ version = "0.4.0"
8
+ description = "Driver-agnostic Robot Framework keyword library core for GUI test automation (OKW4Robot)."
9
+ authors = [{ name = "Zoltán Hrabovszki" }]
10
+ readme = "README.md"
11
+ license = { file = "LICENSE" }
12
+ requires-python = ">=3.10"
13
+ keywords = ["robotframework", "testing", "testautomation", "gui", "okw", "okw4robot"]
14
+ dependencies = [
15
+ "robotframework>=6.0",
16
+ "PyYAML>=6.0",
17
+ "okw-contract-utils>=0.2.0",
18
+ ]
19
+ classifiers = [
20
+ "Development Status :: 4 - Beta",
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3 :: Only",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Programming Language :: Python :: 3.13",
28
+ "Framework :: Robot Framework",
29
+ "Framework :: Robot Framework :: Library",
30
+ "Topic :: Software Development :: Testing",
31
+ ]
32
+
33
+ [project.urls]
34
+ Repository = "https://github.com/Hrabovszki1023/robotframework-okw4robot"
35
+ Homepage = "https://github.com/Hrabovszki1023/robotframework-okw4robot"
36
+ Documentation = "https://hrabovszki1023.github.io/robotframework-okw4robot/"
37
+
38
+ [tool.setuptools]
39
+ package-dir = {"" = "src"}
40
+ include-package-data = true
41
+
42
+ [tool.setuptools.packages.find]
43
+ where = ["src"]
44
+ namespaces = false
45
+
46
+ [project.optional-dependencies]
47
+ dev = ["pytest>=7.0"]
48
+
49
+ [tool.pytest.ini_options]
50
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ from .library import OKW4RobotLibrary
2
+
3
+ __all__ = ["OKW4RobotLibrary"]
@@ -0,0 +1,37 @@
1
+ from robot.api.deco import keyword
2
+ from ..runtime.context import context
3
+ from ..utils.yaml_loader import load_yaml_with_fallback
4
+ from ..utils.logging_mixin import LoggingMixin
5
+
6
+ class AppKeywords(LoggingMixin):
7
+
8
+ @keyword("StartApp")
9
+ def start_app(self, name: str):
10
+ self.log_info(f"Starte App '{name}'...")
11
+ model = load_yaml_with_fallback(name)
12
+ app_name = name.rsplit("/", 1)[-1]
13
+
14
+ if app_name not in model:
15
+ self.log_error(f"App name '{app_name}' not found in YAML root.")
16
+ raise KeyError(f"App name '{app_name}' not found in YAML root")
17
+
18
+ app_model = model[app_name]
19
+ context.set_app(app_name, app_model)
20
+ self.log_info(f"App '{app_name}' gestartet.")
21
+
22
+ @keyword("SelectWindow")
23
+ def select_window(self, name: str):
24
+ self.log_info(f"Wähle Fenster/Widget '{name}'...")
25
+ context.set_window(name)
26
+ self.log_info(f"Fenster/Widget '{name}' aktiviert.")
27
+
28
+ @keyword("StopApp")
29
+ def stop_app(self):
30
+ if context._app_model is None:
31
+ self.log_error("Keine App aktiv – nichts zu stoppen.")
32
+ raise RuntimeError("Stop App failed: No app is currently active.")
33
+
34
+ self.log_info(f"Beende App '{context._app_name}'.")
35
+ context.stop_app()
36
+
37
+
@@ -0,0 +1,54 @@
1
+ from robot.api.deco import keyword
2
+ from robot.api import logger
3
+ from ..utils.okw_helpers import should_ignore, get_robot_timeout, resolve_widget, verify_with_timeout, normalize_var_name
4
+ from okw_contract_utils import MatchMode
5
+
6
+
7
+ def _get_attr(w, attr_name: str) -> str:
8
+ try:
9
+ val = w.okw_get_attribute(attr_name)
10
+ return "" if val is None else str(val)
11
+ except Exception:
12
+ return ""
13
+
14
+
15
+ class AttributeKeywords:
16
+ @keyword("VerifyAttribute")
17
+ def verify_attribute(self, name, attribute, expected):
18
+ if should_ignore(expected):
19
+ logger.info(f"[VerifyAttribute] '{name}' ignored ($IGNORE)")
20
+ return
21
+ w = resolve_widget(name)
22
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_ATTRIBUTE}", 10.0)
23
+ verify_with_timeout(lambda: _get_attr(w, attribute), expected, MatchMode.EXACT, timeout, f"[VerifyAttribute] '{name}'")
24
+
25
+ @keyword("VerifyAttributeWCM")
26
+ def verify_attribute_wcm(self, name, attribute, expected):
27
+ if should_ignore(expected):
28
+ logger.info(f"[VerifyAttributeWCM] '{name}' ignored ($IGNORE)")
29
+ return
30
+ w = resolve_widget(name)
31
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_ATTRIBUTE}", 10.0)
32
+ verify_with_timeout(lambda: _get_attr(w, attribute), expected, MatchMode.WCM, timeout, f"[VerifyAttributeWCM] '{name}'")
33
+
34
+ @keyword("VerifyAttributeREGX")
35
+ def verify_attribute_regx(self, name, attribute, expected):
36
+ if should_ignore(expected):
37
+ logger.info(f"[VerifyAttributeREGX] '{name}' ignored ($IGNORE)")
38
+ return
39
+ w = resolve_widget(name)
40
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_ATTRIBUTE}", 10.0)
41
+ verify_with_timeout(lambda: _get_attr(w, attribute), expected, MatchMode.REGX, timeout, f"[VerifyAttributeREGX] '{name}'")
42
+
43
+ @keyword("MemorizeAttribute")
44
+ def memorize_attribute(self, name, attribute, variable):
45
+ from robot.libraries.BuiltIn import BuiltIn
46
+ w = resolve_widget(name)
47
+ value = _get_attr(w, attribute)
48
+ BuiltIn().set_test_variable(normalize_var_name(variable), value)
49
+
50
+ @keyword("LogAttribute")
51
+ def log_attribute(self, name, attribute):
52
+ w = resolve_widget(name)
53
+ value = _get_attr(w, attribute)
54
+ logger.info(f"[LogAttribute] {value}")