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.
- persona_dsl/__init__.py +35 -0
- persona_dsl/components/action.py +10 -0
- persona_dsl/components/base_step.py +251 -0
- persona_dsl/components/combined_step.py +68 -0
- persona_dsl/components/expectation.py +10 -0
- persona_dsl/components/fact.py +10 -0
- persona_dsl/components/goal.py +10 -0
- persona_dsl/components/ops.py +7 -0
- persona_dsl/components/step.py +75 -0
- persona_dsl/expectations/generic/__init__.py +15 -0
- persona_dsl/expectations/generic/contains_item.py +19 -0
- persona_dsl/expectations/generic/contains_the_text.py +15 -0
- persona_dsl/expectations/generic/has_entries.py +21 -0
- persona_dsl/expectations/generic/is_equal.py +24 -0
- persona_dsl/expectations/generic/is_greater_than.py +18 -0
- persona_dsl/expectations/generic/path_equal.py +27 -0
- persona_dsl/expectations/web/__init__.py +5 -0
- persona_dsl/expectations/web/is_displayed.py +13 -0
- persona_dsl/expectations/web/matches_aria_snapshot.py +221 -0
- persona_dsl/expectations/web/matches_screenshot.py +160 -0
- persona_dsl/generators/__init__.py +5 -0
- persona_dsl/generators/api_generator.py +423 -0
- persona_dsl/generators/cli.py +431 -0
- persona_dsl/generators/page_generator.py +1140 -0
- persona_dsl/ops/api/__init__.py +5 -0
- persona_dsl/ops/api/json_as.py +104 -0
- persona_dsl/ops/api/json_response.py +48 -0
- persona_dsl/ops/api/send_request.py +41 -0
- persona_dsl/ops/db/__init__.py +5 -0
- persona_dsl/ops/db/execute_sql.py +22 -0
- persona_dsl/ops/db/fetch_all.py +29 -0
- persona_dsl/ops/db/fetch_one.py +22 -0
- persona_dsl/ops/kafka/__init__.py +4 -0
- persona_dsl/ops/kafka/message_in_topic.py +89 -0
- persona_dsl/ops/kafka/send_message.py +35 -0
- persona_dsl/ops/soap/__init__.py +4 -0
- persona_dsl/ops/soap/call_operation.py +24 -0
- persona_dsl/ops/soap/operation_result.py +24 -0
- persona_dsl/ops/web/__init__.py +37 -0
- persona_dsl/ops/web/aria_snapshot.py +87 -0
- persona_dsl/ops/web/click.py +30 -0
- persona_dsl/ops/web/current_path.py +17 -0
- persona_dsl/ops/web/element_attribute.py +24 -0
- persona_dsl/ops/web/element_is_visible.py +27 -0
- persona_dsl/ops/web/element_text.py +28 -0
- persona_dsl/ops/web/elements_count.py +42 -0
- persona_dsl/ops/web/fill.py +41 -0
- persona_dsl/ops/web/generate_page_object.py +118 -0
- persona_dsl/ops/web/input_value.py +23 -0
- persona_dsl/ops/web/navigate.py +52 -0
- persona_dsl/ops/web/press_key.py +37 -0
- persona_dsl/ops/web/rich_aria_snapshot.py +146 -0
- persona_dsl/ops/web/screenshot.py +68 -0
- persona_dsl/ops/web/table_data.py +43 -0
- persona_dsl/ops/web/wait_for_navigation.py +23 -0
- persona_dsl/pages/__init__.py +133 -0
- persona_dsl/pages/elements.py +998 -0
- persona_dsl/pages/page.py +44 -0
- persona_dsl/pages/virtual_page.py +94 -0
- persona_dsl/persona.py +125 -0
- persona_dsl/pytest_plugin.py +1064 -0
- persona_dsl/runtime/dist/persona_bundle.js +1077 -0
- persona_dsl/skills/__init__.py +7 -0
- persona_dsl/skills/core/base.py +41 -0
- persona_dsl/skills/core/skill_definition.py +30 -0
- persona_dsl/skills/use_api.py +251 -0
- persona_dsl/skills/use_browser.py +78 -0
- persona_dsl/skills/use_database.py +129 -0
- persona_dsl/skills/use_kafka.py +135 -0
- persona_dsl/skills/use_soap.py +66 -0
- persona_dsl/utils/__init__.py +0 -0
- persona_dsl/utils/artifacts.py +22 -0
- persona_dsl/utils/config.py +54 -0
- persona_dsl/utils/data_providers.py +159 -0
- persona_dsl/utils/decorators.py +80 -0
- persona_dsl/utils/metrics.py +69 -0
- persona_dsl/utils/naming.py +14 -0
- persona_dsl/utils/path.py +202 -0
- persona_dsl/utils/retry.py +51 -0
- persona_dsl/utils/taas_integration.py +124 -0
- persona_dsl/utils/waits.py +112 -0
- persona_dsl-26.1.20.8.dist-info/METADATA +35 -0
- persona_dsl-26.1.20.8.dist-info/RECORD +86 -0
- persona_dsl-26.1.20.8.dist-info/WHEEL +5 -0
- persona_dsl-26.1.20.8.dist-info/entry_points.txt +6 -0
- 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 @@
|
|
|
1
|
+
persona_dsl
|