robotframework-okw4robot 0.4.0__py3-none-any.whl

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.
okw4robot/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from .library import OKW4RobotLibrary
2
+
3
+ __all__ = ["OKW4RobotLibrary"]
File without changes
@@ -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}")
@@ -0,0 +1,53 @@
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_caption(w) -> str:
8
+ try:
9
+ return w.okw_get_text() or ""
10
+ except Exception:
11
+ return ""
12
+
13
+
14
+ class CaptionKeywords:
15
+ @keyword("VerifyCaption")
16
+ def verify_caption(self, name, expected):
17
+ if should_ignore(expected):
18
+ logger.info(f"[VerifyCaption] '{name}' ignored ($IGNORE)")
19
+ return
20
+ w = resolve_widget(name)
21
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_CAPTION}", 10.0)
22
+ verify_with_timeout(lambda: _get_caption(w), expected, MatchMode.EXACT, timeout, f"[VerifyCaption] '{name}'")
23
+
24
+ @keyword("VerifyCaptionWCM")
25
+ def verify_caption_wcm(self, name, expected):
26
+ if should_ignore(expected):
27
+ logger.info(f"[VerifyCaptionWCM] '{name}' ignored ($IGNORE)")
28
+ return
29
+ w = resolve_widget(name)
30
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_CAPTION}", 10.0)
31
+ verify_with_timeout(lambda: _get_caption(w), expected, MatchMode.WCM, timeout, f"[VerifyCaptionWCM] '{name}'")
32
+
33
+ @keyword("VerifyCaptionREGX")
34
+ def verify_caption_regx(self, name, expected):
35
+ if should_ignore(expected):
36
+ logger.info(f"[VerifyCaptionREGX] '{name}' ignored ($IGNORE)")
37
+ return
38
+ w = resolve_widget(name)
39
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_CAPTION}", 10.0)
40
+ verify_with_timeout(lambda: _get_caption(w), expected, MatchMode.REGX, timeout, f"[VerifyCaptionREGX] '{name}'")
41
+
42
+ @keyword("MemorizeCaption")
43
+ def memorize_caption(self, name, variable):
44
+ from robot.libraries.BuiltIn import BuiltIn
45
+ w = resolve_widget(name)
46
+ value = _get_caption(w)
47
+ BuiltIn().set_test_variable(normalize_var_name(variable), value)
48
+
49
+ @keyword("LogCaption")
50
+ def log_caption(self, name):
51
+ w = resolve_widget(name)
52
+ value = _get_caption(w)
53
+ logger.info(f"[LogCaption] {value}")
@@ -0,0 +1,35 @@
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.loader import load_class
5
+ from ..utils.logging_mixin import LoggingMixin
6
+
7
+
8
+ class HostKeywords(LoggingMixin):
9
+
10
+ @keyword("StartHost")
11
+ def start_host(self, name: str):
12
+ self.log_info(f"Starte Host '{name}'...")
13
+ model = load_yaml_with_fallback(name)
14
+ adapter_cls = load_class(model[name]["__self__"]["class"])
15
+ adapter_args = {k: v for k, v in model[name]["__self__"].items() if k != "class"}
16
+ adapter = adapter_cls(**adapter_args)
17
+ context.set_adapter(adapter)
18
+ self.log_info(f"Host '{name}' erfolgreich gestartet.")
19
+
20
+ @keyword("SelectHost")
21
+ def select_host(self, name: str):
22
+ current = context.get_adapter().__class__.__name__
23
+ self.log_info(f"Prüfe, ob Host '{name}' aktiv ist...")
24
+ if current.lower() != name.lower():
25
+ self.log_error(f"Host-Kontextfehler: '{name}' ist nicht aktiv (aktuell: '{current}')")
26
+ raise RuntimeError(f"Host '{name}' is not active (currently: '{current}')")
27
+ self.log_info(f"Host '{name}' ist aktiv.")
28
+
29
+ @keyword("StopHost")
30
+ def stop_host(self):
31
+ self.log_info("Stoppe aktuellen Host...")
32
+ context.stop_adapter()
33
+ self.log_info("Host wurde gestoppt.")
34
+
35
+
@@ -0,0 +1,53 @@
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_label(w) -> str:
8
+ try:
9
+ return w.okw_get_label() or ""
10
+ except Exception:
11
+ return ""
12
+
13
+
14
+ class LabelKeywords:
15
+ @keyword("VerifyLabel")
16
+ def verify_label(self, name, expected):
17
+ if should_ignore(expected):
18
+ logger.info(f"[VerifyLabel] '{name}' ignored ($IGNORE)")
19
+ return
20
+ w = resolve_widget(name)
21
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_LABEL}", 10.0)
22
+ verify_with_timeout(lambda: _get_label(w), expected, MatchMode.EXACT, timeout, f"[VerifyLabel] '{name}'")
23
+
24
+ @keyword("VerifyLabelWCM")
25
+ def verify_label_wcm(self, name, expected):
26
+ if should_ignore(expected):
27
+ logger.info(f"[VerifyLabelWCM] '{name}' ignored ($IGNORE)")
28
+ return
29
+ w = resolve_widget(name)
30
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_LABEL}", 10.0)
31
+ verify_with_timeout(lambda: _get_label(w), expected, MatchMode.WCM, timeout, f"[VerifyLabelWCM] '{name}'")
32
+
33
+ @keyword("VerifyLabelREGX")
34
+ def verify_label_regx(self, name, expected):
35
+ if should_ignore(expected):
36
+ logger.info(f"[VerifyLabelREGX] '{name}' ignored ($IGNORE)")
37
+ return
38
+ w = resolve_widget(name)
39
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_LABEL}", 10.0)
40
+ verify_with_timeout(lambda: _get_label(w), expected, MatchMode.REGX, timeout, f"[VerifyLabelREGX] '{name}'")
41
+
42
+ @keyword("MemorizeLabel")
43
+ def memorize_label(self, name, variable):
44
+ from robot.libraries.BuiltIn import BuiltIn
45
+ w = resolve_widget(name)
46
+ value = _get_label(w)
47
+ BuiltIn().set_test_variable(normalize_var_name(variable), value)
48
+
49
+ @keyword("LogLabel")
50
+ def log_label(self, name):
51
+ w = resolve_widget(name)
52
+ value = _get_label(w)
53
+ logger.info(f"[LogLabel] {value}")
@@ -0,0 +1,72 @@
1
+ import time
2
+ from robot.api.deco import keyword
3
+ from ..runtime.context import context
4
+ from ..utils.okw_helpers import get_robot_timeout, get_robot_poll, resolve_widget
5
+
6
+
7
+ class ListKeywords:
8
+ @keyword("VerifyListCount")
9
+ def verify_list_count(self, name: str, expected_count):
10
+ """Verifies the number of items in a list-like widget.
11
+
12
+ Arguments:
13
+ - ``name``: Logical widget name from the current window (YAML model).
14
+ - ``expected_count``: Integer expected number of items.
15
+
16
+ Behavior:
17
+ - Resolves the widget and polls ``okw_get_list_count()`` until the count equals the expected.
18
+ - Timing via ``${OKW_TIMEOUT_VERIFY_LIST}`` (default 2s) and ``${OKW_POLL_VERIFY}`` (default 0.1s).
19
+
20
+ Supported widgets (base implementation): ListBox, RadioList, native <select> ComboBox.
21
+ """
22
+ try:
23
+ exp = int(str(expected_count).strip())
24
+ except Exception:
25
+ raise ValueError(f"[VerifyListCount] Expected must be integer, got '{expected_count}'")
26
+ w = resolve_widget(name)
27
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_LIST}", 2.0)
28
+ poll = get_robot_poll()
29
+ end = time.monotonic() + timeout
30
+ while time.monotonic() < end:
31
+ try:
32
+ got = int(w.okw_get_list_count())
33
+ except NotImplementedError as e:
34
+ raise RuntimeError(f"[VerifyListCount] Not supported by widget '{name}': {e}")
35
+ if got == exp:
36
+ return
37
+ time.sleep(poll)
38
+ got = int(w.okw_get_list_count())
39
+ raise AssertionError(f"[VerifyListCount] Expected {exp}, got {got}")
40
+
41
+ @keyword("VerifySelectedCount")
42
+ def verify_selected_count(self, name: str, expected_count):
43
+ """Verifies the number of selected items in a list-like widget.
44
+
45
+ Arguments:
46
+ - ``name``: Logical widget name from the current window (YAML model).
47
+ - ``expected_count``: Integer expected selected count.
48
+
49
+ Behavior:
50
+ - Resolves the widget and polls ``okw_get_selected_count()`` until the count equals the expected.
51
+ - Timing via ``${OKW_TIMEOUT_VERIFY_LIST}`` (default 2s) and ``${OKW_POLL_VERIFY}`` (default 0.1s).
52
+
53
+ Supported widgets (base implementation): ListBox, RadioList, ComboBox (0/1).
54
+ """
55
+ try:
56
+ exp = int(str(expected_count).strip())
57
+ except Exception:
58
+ raise ValueError(f"[VerifySelectedCount] Expected must be integer, got '{expected_count}'")
59
+ w = resolve_widget(name)
60
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_LIST}", 2.0)
61
+ poll = get_robot_poll()
62
+ end = time.monotonic() + timeout
63
+ while time.monotonic() < end:
64
+ try:
65
+ got = int(w.okw_get_selected_count())
66
+ except NotImplementedError as e:
67
+ raise RuntimeError(f"[VerifySelectedCount] Not supported by widget '{name}': {e}")
68
+ if got == exp:
69
+ return
70
+ time.sleep(poll)
71
+ got = int(w.okw_get_selected_count())
72
+ raise AssertionError(f"[VerifySelectedCount] Expected {exp}, got {got}")
@@ -0,0 +1,43 @@
1
+ from robot.api.deco import keyword
2
+
3
+
4
+ class ParamsKeywords:
5
+ @keyword("SetOKWParameter")
6
+ def set_okw_parameter(self, name: str, value):
7
+ """Sets OKW runtime parameters such as timeouts.
8
+
9
+ Supported names (case-insensitive):
10
+ - TimeOutVerifyValue
11
+ - TimeOutVerifyTooltip
12
+ - TimeOutVerifyPlaceholder
13
+
14
+ Value may be seconds (number) or Robot time string (e.g. '10s').
15
+ Scope: suite variable.
16
+ """
17
+ mapping = {
18
+ "TIMEOUTVERIFYVALUE": "${OKW_TIMEOUT_VERIFY_VALUE}",
19
+ "TIMEOUTVERIFYTOOLTIP": "${OKW_TIMEOUT_VERIFY_TOOLTIP}",
20
+ "TIMEOUTVERIFYPLACEHOLDER": "${OKW_TIMEOUT_VERIFY_PLACEHOLDER}",
21
+ "TIMEOUTVERIFYLABEL": "${OKW_TIMEOUT_VERIFY_LABEL}",
22
+ "TIMEOUTVERIFYCAPTION": "${OKW_TIMEOUT_VERIFY_CAPTION}",
23
+ "TIMEOUTVERIFYATTRIBUTE": "${OKW_TIMEOUT_VERIFY_ATTRIBUTE}",
24
+ # New timeouts for state verification
25
+ "TIMEOUTVERIFYEXIST": "${OKW_TIMEOUT_VERIFY_EXIST}",
26
+ "TIMEOUTVERIFYVISIBLE": "${OKW_TIMEOUT_VERIFY_VISIBLE}",
27
+ "TIMEOUTVERIFYENABLED": "${OKW_TIMEOUT_VERIFY_ENABLED}",
28
+ "TIMEOUTVERIFYEDITABLE": "${OKW_TIMEOUT_VERIFY_EDITABLE}",
29
+ "TIMEOUTVERIFYFOCUSABLE": "${OKW_TIMEOUT_VERIFY_FOCUSABLE}",
30
+ "TIMEOUTVERIFYCLICKABLE": "${OKW_TIMEOUT_VERIFY_CLICKABLE}",
31
+ "TIMEOUTVERIFYFOCUS": "${OKW_TIMEOUT_VERIFY_FOCUS}",
32
+ # Table verification timeout
33
+ "TIMEOUTVERIFYTABLE": "${OKW_TIMEOUT_VERIFY_TABLE}",
34
+ # Poll interval for verify loops
35
+ "POLLVERIFY": "${OKW_POLL_VERIFY}",
36
+ }
37
+ key = str(name or "").strip().upper()
38
+ if key not in mapping:
39
+ raise ValueError(f"Unsupported OKW parameter: {name}")
40
+ var_name = mapping[key]
41
+ from robot.libraries.BuiltIn import BuiltIn
42
+ # Keep raw value; readers will convert appropriately
43
+ BuiltIn().set_suite_variable(var_name, value)
@@ -0,0 +1,53 @@
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_placeholder(w) -> str:
8
+ try:
9
+ return w.okw_get_placeholder() or ""
10
+ except Exception:
11
+ return ""
12
+
13
+
14
+ class PlaceholderKeywords:
15
+ @keyword("VerifyPlaceholder")
16
+ def verify_placeholder(self, name, expected):
17
+ if should_ignore(expected):
18
+ logger.info(f"[VerifyPlaceholder] '{name}' ignored ($IGNORE)")
19
+ return
20
+ w = resolve_widget(name)
21
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_PLACEHOLDER}", 10.0)
22
+ verify_with_timeout(lambda: _get_placeholder(w), expected, MatchMode.EXACT, timeout, f"[VerifyPlaceholder] '{name}'")
23
+
24
+ @keyword("VerifyPlaceholderWCM")
25
+ def verify_placeholder_wcm(self, name, expected):
26
+ if should_ignore(expected):
27
+ logger.info(f"[VerifyPlaceholderWCM] '{name}' ignored ($IGNORE)")
28
+ return
29
+ w = resolve_widget(name)
30
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_PLACEHOLDER}", 10.0)
31
+ verify_with_timeout(lambda: _get_placeholder(w), expected, MatchMode.WCM, timeout, f"[VerifyPlaceholderWCM] '{name}'")
32
+
33
+ @keyword("VerifyPlaceholderREGX")
34
+ def verify_placeholder_regx(self, name, expected):
35
+ if should_ignore(expected):
36
+ logger.info(f"[VerifyPlaceholderREGX] '{name}' ignored ($IGNORE)")
37
+ return
38
+ w = resolve_widget(name)
39
+ timeout = get_robot_timeout("${OKW_TIMEOUT_VERIFY_PLACEHOLDER}", 10.0)
40
+ verify_with_timeout(lambda: _get_placeholder(w), expected, MatchMode.REGX, timeout, f"[VerifyPlaceholderREGX] '{name}'")
41
+
42
+ @keyword("MemorizePlaceholder")
43
+ def memorize_placeholder(self, name, variable):
44
+ from robot.libraries.BuiltIn import BuiltIn
45
+ w = resolve_widget(name)
46
+ value = _get_placeholder(w)
47
+ BuiltIn().set_test_variable(normalize_var_name(variable), value)
48
+
49
+ @keyword("LogPlaceholder")
50
+ def log_placeholder(self, name):
51
+ w = resolve_widget(name)
52
+ value = _get_placeholder(w)
53
+ logger.info(f"[LogPlaceholder] {value}")