persona-dsl 26.1.20.8__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.
Files changed (86) hide show
  1. persona_dsl/__init__.py +35 -0
  2. persona_dsl/components/action.py +10 -0
  3. persona_dsl/components/base_step.py +251 -0
  4. persona_dsl/components/combined_step.py +68 -0
  5. persona_dsl/components/expectation.py +10 -0
  6. persona_dsl/components/fact.py +10 -0
  7. persona_dsl/components/goal.py +10 -0
  8. persona_dsl/components/ops.py +7 -0
  9. persona_dsl/components/step.py +75 -0
  10. persona_dsl/expectations/generic/__init__.py +15 -0
  11. persona_dsl/expectations/generic/contains_item.py +19 -0
  12. persona_dsl/expectations/generic/contains_the_text.py +15 -0
  13. persona_dsl/expectations/generic/has_entries.py +21 -0
  14. persona_dsl/expectations/generic/is_equal.py +24 -0
  15. persona_dsl/expectations/generic/is_greater_than.py +18 -0
  16. persona_dsl/expectations/generic/path_equal.py +27 -0
  17. persona_dsl/expectations/web/__init__.py +5 -0
  18. persona_dsl/expectations/web/is_displayed.py +13 -0
  19. persona_dsl/expectations/web/matches_aria_snapshot.py +221 -0
  20. persona_dsl/expectations/web/matches_screenshot.py +160 -0
  21. persona_dsl/generators/__init__.py +5 -0
  22. persona_dsl/generators/api_generator.py +423 -0
  23. persona_dsl/generators/cli.py +431 -0
  24. persona_dsl/generators/page_generator.py +1140 -0
  25. persona_dsl/ops/api/__init__.py +5 -0
  26. persona_dsl/ops/api/json_as.py +104 -0
  27. persona_dsl/ops/api/json_response.py +48 -0
  28. persona_dsl/ops/api/send_request.py +41 -0
  29. persona_dsl/ops/db/__init__.py +5 -0
  30. persona_dsl/ops/db/execute_sql.py +22 -0
  31. persona_dsl/ops/db/fetch_all.py +29 -0
  32. persona_dsl/ops/db/fetch_one.py +22 -0
  33. persona_dsl/ops/kafka/__init__.py +4 -0
  34. persona_dsl/ops/kafka/message_in_topic.py +89 -0
  35. persona_dsl/ops/kafka/send_message.py +35 -0
  36. persona_dsl/ops/soap/__init__.py +4 -0
  37. persona_dsl/ops/soap/call_operation.py +24 -0
  38. persona_dsl/ops/soap/operation_result.py +24 -0
  39. persona_dsl/ops/web/__init__.py +37 -0
  40. persona_dsl/ops/web/aria_snapshot.py +87 -0
  41. persona_dsl/ops/web/click.py +30 -0
  42. persona_dsl/ops/web/current_path.py +17 -0
  43. persona_dsl/ops/web/element_attribute.py +24 -0
  44. persona_dsl/ops/web/element_is_visible.py +27 -0
  45. persona_dsl/ops/web/element_text.py +28 -0
  46. persona_dsl/ops/web/elements_count.py +42 -0
  47. persona_dsl/ops/web/fill.py +41 -0
  48. persona_dsl/ops/web/generate_page_object.py +118 -0
  49. persona_dsl/ops/web/input_value.py +23 -0
  50. persona_dsl/ops/web/navigate.py +52 -0
  51. persona_dsl/ops/web/press_key.py +37 -0
  52. persona_dsl/ops/web/rich_aria_snapshot.py +146 -0
  53. persona_dsl/ops/web/screenshot.py +68 -0
  54. persona_dsl/ops/web/table_data.py +43 -0
  55. persona_dsl/ops/web/wait_for_navigation.py +23 -0
  56. persona_dsl/pages/__init__.py +133 -0
  57. persona_dsl/pages/elements.py +998 -0
  58. persona_dsl/pages/page.py +44 -0
  59. persona_dsl/pages/virtual_page.py +94 -0
  60. persona_dsl/persona.py +125 -0
  61. persona_dsl/pytest_plugin.py +1064 -0
  62. persona_dsl/runtime/dist/persona_bundle.js +1077 -0
  63. persona_dsl/skills/__init__.py +7 -0
  64. persona_dsl/skills/core/base.py +41 -0
  65. persona_dsl/skills/core/skill_definition.py +30 -0
  66. persona_dsl/skills/use_api.py +251 -0
  67. persona_dsl/skills/use_browser.py +78 -0
  68. persona_dsl/skills/use_database.py +129 -0
  69. persona_dsl/skills/use_kafka.py +135 -0
  70. persona_dsl/skills/use_soap.py +66 -0
  71. persona_dsl/utils/__init__.py +0 -0
  72. persona_dsl/utils/artifacts.py +22 -0
  73. persona_dsl/utils/config.py +54 -0
  74. persona_dsl/utils/data_providers.py +159 -0
  75. persona_dsl/utils/decorators.py +80 -0
  76. persona_dsl/utils/metrics.py +69 -0
  77. persona_dsl/utils/naming.py +14 -0
  78. persona_dsl/utils/path.py +202 -0
  79. persona_dsl/utils/retry.py +51 -0
  80. persona_dsl/utils/taas_integration.py +124 -0
  81. persona_dsl/utils/waits.py +112 -0
  82. persona_dsl-26.1.20.8.dist-info/METADATA +35 -0
  83. persona_dsl-26.1.20.8.dist-info/RECORD +86 -0
  84. persona_dsl-26.1.20.8.dist-info/WHEEL +5 -0
  85. persona_dsl-26.1.20.8.dist-info/entry_points.txt +6 -0
  86. persona_dsl-26.1.20.8.dist-info/top_level.txt +1 -0
@@ -0,0 +1,51 @@
1
+ from __future__ import annotations
2
+
3
+ import time
4
+ from dataclasses import dataclass
5
+ from typing import Callable, Optional, Tuple, Type
6
+
7
+
8
+ @dataclass
9
+ class RetryPolicy:
10
+ """
11
+ Политика повторных попыток (ретраев).
12
+
13
+ Attributes:
14
+ max_attempts: Максимальное количество попыток (включая первую). По умолчанию 1 (без ретраев).
15
+ delay: Задержка между попытками в секундах.
16
+ backoff_factor: Множитель увеличения задержки (экспоненциальный рост).
17
+ retry_on: Кортеж типов исключений, при которых нужно повторять попытку.
18
+ retry_if: Предикат для проверки экземпляра исключения (вернуть True, если нужно повторить).
19
+ on_retry_action: Коллбек, вызываемый перед каждой повторной попыткой.
20
+ """
21
+
22
+ max_attempts: int = 1
23
+ delay: float = 0.0
24
+ backoff_factor: float = 1.0
25
+ retry_on: Tuple[Type[Exception], ...] = (Exception,)
26
+ retry_if: Optional[Callable[[Exception], bool]] = None
27
+ on_retry_action: Optional[Callable[[], None]] = None
28
+
29
+ def should_retry(self, attempt: int, exception: Exception) -> bool:
30
+ """Определяет, нужно ли делать ретрай."""
31
+ if attempt >= self.max_attempts:
32
+ return False
33
+
34
+ if not isinstance(exception, self.retry_on):
35
+ return False
36
+
37
+ if self.retry_if is not None and not self.retry_if(exception):
38
+ return False
39
+
40
+ return True
41
+
42
+ def wait(self, attempt: int) -> None:
43
+ """Выполняет ожидание перед следующей попыткой."""
44
+ wait_time = self.delay * (self.backoff_factor ** (attempt - 1))
45
+ if wait_time > 0:
46
+ time.sleep(wait_time)
47
+
48
+ def execute_action(self) -> None:
49
+ """Выполняет действие перед ретраем (если задано)."""
50
+ if self.on_retry_action:
51
+ self.on_retry_action()
@@ -0,0 +1,124 @@
1
+ import json
2
+ import os
3
+ import redis
4
+ import logging
5
+ from typing import Optional, Any
6
+
7
+ _taas_redis_client: Optional[redis.Redis] = None
8
+ _taas_redis_mod: Optional[Any] = None
9
+ _taas_connection_failed: bool = False
10
+
11
+
12
+ def reset_taas_redis_client() -> None:
13
+ """Сбрасывает кеш клиента Redis (для переинициализации соединения)."""
14
+ global _taas_redis_client, _taas_redis_mod, _taas_connection_failed
15
+ _taas_redis_client = None
16
+ _taas_redis_mod = None
17
+ _taas_connection_failed = False
18
+
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ def _connect_or_raise() -> Optional[redis.Redis]:
24
+ redis_url = os.environ.get("REDIS_URL", "redis://localhost:6379")
25
+ try:
26
+ client = redis.from_url(redis_url, decode_responses=True)
27
+ client.ping()
28
+ return client
29
+ except Exception as e:
30
+ is_strict = os.environ.get("TAAS_STRICT_CONNECT", "false").lower() not in (
31
+ "false",
32
+ "0",
33
+ )
34
+ if is_strict:
35
+ raise RuntimeError(
36
+ f"[TAAS_INTEGRATION] Не удалось подключиться к Redis по REDIS_URL={redis_url}: {e}"
37
+ ) from e
38
+ logger.warning(
39
+ f"[TAAS_INTEGRATION] Non-strict mode: Не удалось подключиться к Redis. "
40
+ f"События TaaS будут отключены. Ошибка: {e}"
41
+ )
42
+ return None
43
+
44
+
45
+ def get_taas_redis_client() -> Optional[redis.Redis]:
46
+ """Инициализирует и возвращает клиент Redis, если запуск в контексте TaaS."""
47
+ global _taas_redis_client, _taas_redis_mod, _taas_connection_failed
48
+ if not os.environ.get("TAAS_RUN_ID") or _taas_connection_failed:
49
+ return None
50
+
51
+ if _taas_redis_mod is not None and _taas_redis_mod is not redis:
52
+ reset_taas_redis_client()
53
+
54
+ if _taas_redis_client is None:
55
+ _taas_redis_client = _connect_or_raise()
56
+ if _taas_redis_client is None:
57
+ _taas_connection_failed = True
58
+ return None
59
+ _taas_redis_mod = redis
60
+ return _taas_redis_client
61
+
62
+ try:
63
+ _taas_redis_client.ping()
64
+ return _taas_redis_client
65
+ except Exception:
66
+ _taas_redis_client = _connect_or_raise()
67
+ if _taas_redis_client is None:
68
+ _taas_connection_failed = True
69
+ return None
70
+ _taas_redis_mod = redis
71
+ return _taas_redis_client
72
+
73
+
74
+ def publish_taas_event(event_payload: dict) -> None:
75
+ """Публикует событие только в Redis Stream (без Pub/Sub и списков)."""
76
+ run_id = os.environ.get("TAAS_RUN_ID")
77
+ client = get_taas_redis_client()
78
+ if client and run_id:
79
+ # Строгая валидация структуры события
80
+ if not isinstance(event_payload, dict):
81
+ raise TypeError("[TAAS_INTEGRATION] event_payload должен быть dict")
82
+ ev = event_payload.get("event")
83
+ if not isinstance(ev, str) or not ev:
84
+ raise ValueError(
85
+ "[TAAS_INTEGRATION] Событие должно содержать непустое строковое поле 'event'"
86
+ )
87
+ data = event_payload.get("data")
88
+ if not isinstance(data, dict):
89
+ raise ValueError(
90
+ "[TAAS_INTEGRATION] Событие должно содержать объект 'data'"
91
+ )
92
+ if str(ev).startswith("step_"):
93
+ t = event_payload.get("type")
94
+ if not isinstance(t, str) or not t:
95
+ raise ValueError(
96
+ "[TAAS_INTEGRATION] Для step_* событий обязательно строковое поле 'type'"
97
+ )
98
+
99
+ json_payload = json.dumps(event_payload)
100
+
101
+ # Краткая сводка в лог
102
+ try:
103
+ event_type = event_payload.get("event")
104
+ component_type = event_payload.get("type")
105
+ description = event_payload.get("data", {}).get("description")
106
+ status = event_payload.get("data", {}).get("status")
107
+ logger.info(
108
+ f"[TAAS_INTEGRATION] Event: {event_type}, type={component_type}, status={status}, desc={description}"
109
+ )
110
+ except Exception as e:
111
+ logger.exception("Ошибка формирования краткой сводки события TaaS: %s", e)
112
+
113
+ # Только Redis Streams
114
+ stream_key = f"run:{run_id}:events"
115
+ raw_maxlen = os.getenv("TAAS_STREAM_MAXLEN", "10000")
116
+ try:
117
+ maxlen = int(raw_maxlen)
118
+ if maxlen <= 0:
119
+ raise ValueError("TAAS_STREAM_MAXLEN должен быть положительным целым")
120
+ except Exception as e:
121
+ raise RuntimeError(
122
+ f"[TAAS_INTEGRATION] Некорректное значение TAAS_STREAM_MAXLEN={raw_maxlen}: {e}"
123
+ ) from e
124
+ client.xadd(stream_key, {"json": json_payload}, maxlen=maxlen, approximate=True)
@@ -0,0 +1,112 @@
1
+ import random
2
+ import time
3
+ from typing import Any, Callable, Literal, Optional
4
+
5
+ from allure import step
6
+
7
+ from ..components.expectation import Expectation
8
+ from .metrics import metrics
9
+ from .taas_integration import publish_taas_event
10
+
11
+ BackoffMode = Literal["linear", "exp"]
12
+
13
+
14
+ def wait_until(
15
+ fact: Callable[[], Any],
16
+ expectation: Expectation,
17
+ timeout: float = 10.0,
18
+ interval: float = 0.5,
19
+ backoff: BackoffMode = "linear",
20
+ jitter: float = 0.0,
21
+ domain: Optional[str] = None,
22
+ on_timeout: Literal["fail", "warn", "continue"] = "fail",
23
+ ) -> Any:
24
+ """
25
+ Универсальный helper ожиданий.
26
+ Периодически вызывает fact(), проверяя expectation._perform(None, value) до тех пор, пока не истечет timeout.
27
+
28
+ Args:
29
+ fact: вызываемая без аргументов функция, возвращающая значение для проверки.
30
+ expectation: экземпляр класса Expectation с методом check(actual).
31
+ timeout: общий таймаут в секундах.
32
+ interval: базовый интервал между попытками.
33
+ backoff: стратегия увеличения интервала: 'linear' или 'exp'.
34
+ jitter: добавочный случайный шум в секундах, 0 — без шума.
35
+ domain: логический домен ожидания ('ui' | 'api' | 'kafka'), используется в метриках и событиях.
36
+ on_timeout: поведение при истечении таймаута: 'fail' | 'warn' | 'continue'.
37
+ """
38
+ start = time.time()
39
+ attempts = 0
40
+ status = "running"
41
+ description = f"Ожидание: {expectation.__class__.__name__}"
42
+
43
+ publish_taas_event(
44
+ {
45
+ "event": "step_start",
46
+ "type": "wait",
47
+ "data": {
48
+ "description": description,
49
+ "timestamp": start,
50
+ "component_name": expectation.__class__.__name__,
51
+ "component_params": {
52
+ "timeout": timeout,
53
+ "interval": interval,
54
+ "backoff": backoff,
55
+ "jitter": jitter,
56
+ "domain": domain,
57
+ },
58
+ },
59
+ }
60
+ )
61
+
62
+ try:
63
+ with step(description):
64
+ while True:
65
+ attempts += 1
66
+ value = fact()
67
+ try:
68
+ expectation._perform(None, value)
69
+ status = "passed"
70
+ return value
71
+ except Exception:
72
+ # еще не готово, продолжаем ждать
73
+ if time.time() - start >= timeout:
74
+ status = "failed" if on_timeout == "fail" else "passed"
75
+ if on_timeout == "fail":
76
+ raise TimeoutError(
77
+ f"Ожидание не выполнено за {timeout}с: {description}"
78
+ )
79
+ return value
80
+ # вычисляем задержку на следующую попытку
81
+ delay = (
82
+ interval
83
+ if backoff == "linear"
84
+ else interval * (2 ** (attempts - 1))
85
+ )
86
+ if jitter > 0:
87
+ delay += random.uniform(0, jitter)
88
+ time.sleep(min(delay, max(0.0, timeout - (time.time() - start))))
89
+ finally:
90
+ duration = time.time() - start
91
+ metrics.gauge(
92
+ "wait.duration",
93
+ duration,
94
+ {"status": status, "domain": domain or "unspecified"},
95
+ )
96
+ metrics.counter("wait.attempts", {"domain": domain or "unspecified"}).inc(
97
+ attempts
98
+ )
99
+ publish_taas_event(
100
+ {
101
+ "event": "step_end",
102
+ "type": "wait",
103
+ "data": {
104
+ "description": description,
105
+ "timestamp": time.time(),
106
+ "duration": duration,
107
+ "status": status,
108
+ "attempts": attempts,
109
+ "domain": domain,
110
+ },
111
+ }
112
+ )
@@ -0,0 +1,35 @@
1
+ Metadata-Version: 2.4
2
+ Name: persona-dsl
3
+ Version: 26.1.20.8
4
+ Summary: DSL для реализации паттерна Screenplay в Python-тестах.
5
+ Requires-Python: >=3.9
6
+ Requires-Dist: playwright==1.55.0
7
+ Requires-Dist: pytest
8
+ Requires-Dist: pytest-cov
9
+ Requires-Dist: allure-pytest
10
+ Requires-Dist: python-dotenv
11
+ Requires-Dist: pyyaml
12
+ Requires-Dist: pydantic<3,>=2
13
+ Requires-Dist: requests
14
+ Requires-Dist: pyhamcrest
15
+ Requires-Dist: redis
16
+ Requires-Dist: Faker
17
+ Requires-Dist: pillow
18
+ Requires-Dist: zeep
19
+ Requires-Dist: pg8000
20
+ Requires-Dist: oracledb
21
+ Requires-Dist: kafka-python
22
+ Requires-Dist: Unidecode>=1.3
23
+ Requires-Dist: black
24
+ Provides-Extra: dev
25
+ Requires-Dist: black; extra == "dev"
26
+ Requires-Dist: ruff; extra == "dev"
27
+ Requires-Dist: mypy; extra == "dev"
28
+ Requires-Dist: pytest-cov; extra == "dev"
29
+ Requires-Dist: pre-commit; extra == "dev"
30
+ Requires-Dist: types-requests; extra == "dev"
31
+ Requires-Dist: types-PyYAML; extra == "dev"
32
+ Requires-Dist: types-redis; extra == "dev"
33
+ Requires-Dist: pytest-asyncio; extra == "dev"
34
+ Requires-Dist: pytest-timeout; extra == "dev"
35
+ Requires-Dist: pytest-xdist; extra == "dev"
@@ -0,0 +1,86 @@
1
+ persona_dsl/__init__.py,sha256=C47lvwHDzdM-fsLOy9knGvB5tbqCS9c_rO1SnG7_sc4,875
2
+ persona_dsl/persona.py,sha256=tQXb6BOYKIQvny-0ry06kneus-jZYyhKwrLq0sjQzks,5278
3
+ persona_dsl/pytest_plugin.py,sha256=CyklaxWz3jZnve4FOIX-czOKK4HVHY07zC9OGvpDRco,47044
4
+ persona_dsl/components/action.py,sha256=z456GYCf10hR1tIYeC7IN1V-7bn5uY1ZwNk053sWEls,218
5
+ persona_dsl/components/base_step.py,sha256=nZJUKu5oHsOhiAW3g7_K82fGXjkg3HMnSLvKdacBHbs,9661
6
+ persona_dsl/components/combined_step.py,sha256=-SEKei_1qFDbnQvtKJBN00MJNnM_bMIPp6X0lhZrSbw,3598
7
+ persona_dsl/components/expectation.py,sha256=i2HtkVPQSXsm8H7G-2yg3PAgaORfxI3PnyTERpe-2uI,223
8
+ persona_dsl/components/fact.py,sha256=bf938rQkoIn5oVRb0a-HgSYH9aL_171uPq_-DYLZgyM,216
9
+ persona_dsl/components/goal.py,sha256=q2YPrUFoykWxXHSJkasK_ITshRlifA-BU9RXWO2P2yI,249
10
+ persona_dsl/components/ops.py,sha256=yPzdCusn4daf09OjLWa0qx1z00oWj7LYxQkOOxrg1AA,188
11
+ persona_dsl/components/step.py,sha256=GmIH01pdaknPjg3SL68FBoElHABoTbyEnSKiCdexyt4,4296
12
+ persona_dsl/expectations/generic/__init__.py,sha256=OZ2fPo6dTVRU1B4tP_YuHm06jd_bVwScqWG5ZK2qLhU,363
13
+ persona_dsl/expectations/generic/contains_item.py,sha256=GL7GJQJy5h6ChwRbkBrjelr1n22LIG3Am2Yd_g3GyPg,756
14
+ persona_dsl/expectations/generic/contains_the_text.py,sha256=8ATPDAD8gEB0fw9Lp2GMFrk4IBBbrTCk7SjODMU0L_g,559
15
+ persona_dsl/expectations/generic/has_entries.py,sha256=voCVBKk7Q41vGj3wZYY-lu2E6I_aZMHdTmeS0Lx2y5Y,860
16
+ persona_dsl/expectations/generic/is_equal.py,sha256=hRrVGfGVKWUZkLLybe5AoTOcD03kUB_ZKE7Qfp2UgI0,857
17
+ persona_dsl/expectations/generic/is_greater_than.py,sha256=k6V34pyxPhHX1V7uDOmxP9QlAi9hDrXd6L9vfvMLfLQ,688
18
+ persona_dsl/expectations/generic/path_equal.py,sha256=cvxwCdfiDXC_WhosfmIRqfwaQUogfU0YhUtP2duPTlI,967
19
+ persona_dsl/expectations/web/__init__.py,sha256=lBKeJqO4GO9yjKID37tbdbzS8iD_bZJlSk7GcJ8LCAM,214
20
+ persona_dsl/expectations/web/is_displayed.py,sha256=VNrGo6yJ_kvmUPrT8gVO0YPL-o-5XMXVM6jsBWqtO9s,578
21
+ persona_dsl/expectations/web/matches_aria_snapshot.py,sha256=2YeO5jbfqQNrdH8mCtizpqOsPnQ1Hd6P3sQtqEiILFA,8657
22
+ persona_dsl/expectations/web/matches_screenshot.py,sha256=JOg9IdREJ7LNOsZpIbXesLiJa0nHAvMmmgl8x3jgV-Y,7376
23
+ persona_dsl/generators/__init__.py,sha256=xgjQ0rhC7p6sRir9MFJ4WGt0CWT1fX3_3rsrcy-wkSk,163
24
+ persona_dsl/generators/api_generator.py,sha256=epA8VEblLt09h5F0oMS04ltn8btDXHtonh4rhDI7OSU,17863
25
+ persona_dsl/generators/cli.py,sha256=vvXrgFZmUs_PtDBJychfIIeRc13Jp2IJvbnycHTdTlI,18278
26
+ persona_dsl/generators/page_generator.py,sha256=PxMUqooXp8HvXtyqrErsaMtOD2YpdEp-Wl_hTkg7vUs,42902
27
+ persona_dsl/ops/api/__init__.py,sha256=6kJaE1wd2Nusk5nBK7CKInMm-x0qjTP202N2LvCYdD8,159
28
+ persona_dsl/ops/api/json_as.py,sha256=0ALfCgkG8quUyTCUIGYt0IWNo_4vwY_orut0uw8sI3Q,3725
29
+ persona_dsl/ops/api/json_response.py,sha256=ipUENkam2I-z6SXy13pfGblzZlC_xJcqJ8q6cvhntIM,1891
30
+ persona_dsl/ops/api/send_request.py,sha256=WH_Bus_p6nqG3qG-_e3Po2E2pAYqPtmmLQmMH9j4WII,1227
31
+ persona_dsl/ops/db/__init__.py,sha256=jGXZxcVdjNK1ObwrNYZ906yghRwtv4ogwmpQNB_aDkQ,150
32
+ persona_dsl/ops/db/execute_sql.py,sha256=ZSKLHHBvxJLcmOAVO5WIaYRf_tKgDnETZUxYJ5b3SsI,804
33
+ persona_dsl/ops/db/fetch_all.py,sha256=OYiMoz12l-rySRPA9q451dk-Ryzck49t2jYRe7Mir-E,1039
34
+ persona_dsl/ops/db/fetch_one.py,sha256=RPsgwDqBpaNleYJVZLoIlR4xO4PPELjTiimKYLT4CFU,840
35
+ persona_dsl/ops/kafka/__init__.py,sha256=bV-znLr2TEEfrnCx2driJwufhbuN5hJUP62Cpeuklxs,128
36
+ persona_dsl/ops/kafka/message_in_topic.py,sha256=_TicXtm1MoRoYgeLiKJwadjUcbpZAKcTQwnfXNRTJvs,3125
37
+ persona_dsl/ops/kafka/send_message.py,sha256=N7rTeZcOgKW9shEHDHwOaisIuQxiHkMy0xzC8m_5tto,1074
38
+ persona_dsl/ops/soap/__init__.py,sha256=MFC8cJNwxzjbwShk06ucya2_FN2WQo7Uqj2CKBBzFgI,136
39
+ persona_dsl/ops/soap/call_operation.py,sha256=AuvL1cuNcTVGKGY9iRFBj779JnztW49dK4OCVPQb-n4,936
40
+ persona_dsl/ops/soap/operation_result.py,sha256=jz9KWysvgOLc1sFZah444F5UWhx5ZOOubPb7nX_TmNI,961
41
+ persona_dsl/ops/web/__init__.py,sha256=E9bYemtUYa411u_bJZowdyINt_uMdI5xm_Q5TYBDCqA,1063
42
+ persona_dsl/ops/web/aria_snapshot.py,sha256=wi3Dbhax_9KhrEUVMxp0Vyw9KBZnBPrPx1IVVHJHxUE,2987
43
+ persona_dsl/ops/web/click.py,sha256=I2tyN4awqooad9t83vB6FOq8qaMEHGrdI-QmYuWd8Go,1243
44
+ persona_dsl/ops/web/current_path.py,sha256=au9Q-P0lXn-i_WHXT8P3r21QdPNodicuJeeScHvXURI,679
45
+ persona_dsl/ops/web/element_attribute.py,sha256=vanVngWmdISQ0zL3JDY-hkevsCu9yUJ2YFXUD5lWQp0,1008
46
+ persona_dsl/ops/web/element_is_visible.py,sha256=xEotfLF9hw83gzRP1ax1Bb7cukC4pUN-BcAA1J7QJAo,1099
47
+ persona_dsl/ops/web/element_text.py,sha256=MQe1uaerDpqi4pp3w0FUw7K1QY1yKgQbV5dvPDCVGVg,1147
48
+ persona_dsl/ops/web/elements_count.py,sha256=ME6bjLCxeZIKkiFBx4-jlJELy-CjHG6yFueKcHhq-9I,2034
49
+ persona_dsl/ops/web/fill.py,sha256=WD4DvcMaTdkUFfVgnWgt05TP3NzQtL48IMcahbDh5l0,1755
50
+ persona_dsl/ops/web/generate_page_object.py,sha256=LoiUNTe4cpY7BGhr9FpwR1oykjaPybZ4PmDLSxvZHQE,5413
51
+ persona_dsl/ops/web/input_value.py,sha256=BAMmJ2XsDBNWT0mjXyCJswwhyk5RJx1dM_zvNtYBjdc,918
52
+ persona_dsl/ops/web/navigate.py,sha256=hsG6PCt6tnKn1BU3a4kZDpAPDubnZzgQv_yNxXchlUo,2241
53
+ persona_dsl/ops/web/press_key.py,sha256=QcTo8PtP0Ks-plBOZ6ojPL8bJerB4IUGhvYJRlCNmtY,1709
54
+ persona_dsl/ops/web/rich_aria_snapshot.py,sha256=sfcABy8v1eje8mSuLCbMJ5PUdyCgyNpEhxs6QeiTV1o,5671
55
+ persona_dsl/ops/web/screenshot.py,sha256=Wue5XKIXXbkDNhS5tkHZ5jty7NHd0LLFrFSQ_F01w7c,2378
56
+ persona_dsl/ops/web/table_data.py,sha256=4nKOUDPofFwzjSUcxiiZauNO7V-jXvNTlXXDmuqZpqQ,1920
57
+ persona_dsl/ops/web/wait_for_navigation.py,sha256=a1026yNa3LmWzacfFLUXnjleID3sfXIZ67G3SZuTxRI,977
58
+ persona_dsl/pages/__init__.py,sha256=eqJdLJ-yOTTpBBCoGSxDQCwjC8k4PKKtCOhIQGfeE6s,1917
59
+ persona_dsl/pages/elements.py,sha256=DLofNRG6W77B_Vk8QMAjdTxxCYPMUt2mv3Yw045T3lc,32711
60
+ persona_dsl/pages/page.py,sha256=Q30hUkd5Cpr_1Tyo7-xaif0IAIDD60bsFS7t0wCCjC4,1355
61
+ persona_dsl/pages/virtual_page.py,sha256=WhSwa6MScu3yUlLmA3NgE0Y5CxTvasPDTTmHZZeSP0E,3737
62
+ persona_dsl/runtime/dist/persona_bundle.js,sha256=Nhiwic3ylp8Q94qKQ_-EDeEVKGtyIo9rRRqwQkKcWSE,36425
63
+ persona_dsl/skills/__init__.py,sha256=zE2YgYZvRYslH4MHiV8VStCwXK0lw1F2RiT07RHGd3Q,238
64
+ persona_dsl/skills/use_api.py,sha256=jMsgGWgociuctGdf-CAznRAS1FNu0IXfTsUJ8Bl7VNU,11318
65
+ persona_dsl/skills/use_browser.py,sha256=uM6bAxjN3ZZfjU_islg83LVtEZTKqsLgchKz4qw7KKE,3290
66
+ persona_dsl/skills/use_database.py,sha256=enJ1C8FdXjVSLm9pWnuBg3oeIISJIMnXNy0OgVktfoo,5601
67
+ persona_dsl/skills/use_kafka.py,sha256=ZwkvzdYw-vuG8pRUTSLXOLBza6Vnif5FS06zgeXdRQs,4686
68
+ persona_dsl/skills/use_soap.py,sha256=FK_ou5lLzpno0JY2Q4_H-ImX69TB3CtMZTdBzWabfoY,2351
69
+ persona_dsl/skills/core/base.py,sha256=KquyGkVKkEQ2TsprlsRoGi3ULgVLukaQeVg1n-q8y0E,1416
70
+ persona_dsl/skills/core/skill_definition.py,sha256=_yU7WCjC9oPg72V9eMBgHmbzKHyqz_pGD6ZLjE-ZRgE,1052
71
+ persona_dsl/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
+ persona_dsl/utils/artifacts.py,sha256=tMiGcw1udjv-9d8m2CG_Kx3HDc7oTWphziNyt0Zm0jA,811
73
+ persona_dsl/utils/config.py,sha256=3qaGsSbLAQaAXTg4sIdxE1zzYDmLxwZjJLqh8Kcu2tw,2033
74
+ persona_dsl/utils/data_providers.py,sha256=piHRgeV48iuqDgLbcIT5F7G3CWTHT3d0LZ8FJye1MPg,5514
75
+ persona_dsl/utils/decorators.py,sha256=Q2ETGhyZa9cHxdPAbJi-crztbC-cAfcrdGflsh4ovhI,3171
76
+ persona_dsl/utils/metrics.py,sha256=yVNuHaGwqKS7AuWFS8k3cFIzVRRRH11yRvi7DS7J5d0,2314
77
+ persona_dsl/utils/naming.py,sha256=wOn6QKCO53B0BaAe5IM8GlzSLKfE2eTJpvRo_WGXslo,504
78
+ persona_dsl/utils/path.py,sha256=wwYUS3euYqwKQdxWHD8Lq93Ln1G0M5LIJ6AMqiwpmDI,7251
79
+ persona_dsl/utils/retry.py,sha256=kBbu6rpySdeaqRzUkgdrsEWrc9PwkvRhYtRzyhrYj9g,2215
80
+ persona_dsl/utils/taas_integration.py,sha256=OZzSjgC1_90eTYXo3WPsCgCtYc35U216SBnxClpdIkw,5046
81
+ persona_dsl/utils/waits.py,sha256=I9e_9rs_0Rju61yx_hS-qwcXd4zNWfVNyfhY0mOHrj0,4386
82
+ persona_dsl-26.1.20.8.dist-info/METADATA,sha256=KNXOfE_w4lSVK1mrUNKwWpgicoj5K6c_rb9EAt7UtbM,1108
83
+ persona_dsl-26.1.20.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
84
+ persona_dsl-26.1.20.8.dist-info/entry_points.txt,sha256=8lYko6uS1gGeYX9_FYbbeO5XV_BP62T7RngyKuKDD7k,180
85
+ persona_dsl-26.1.20.8.dist-info/top_level.txt,sha256=N1YAJab5h4iPt-srbrjzDk6bY40bwR1AHZS5Z0eOzvM,12
86
+ persona_dsl-26.1.20.8.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,6 @@
1
+ [console_scripts]
2
+ persona-api-gen = persona_dsl.generators.cli:api_main
3
+ persona-page-gen = persona_dsl.generators.cli:page_main
4
+
5
+ [pytest11]
6
+ persona_dsl = persona_dsl.pytest_plugin
@@ -0,0 +1 @@
1
+ persona_dsl