persona-dsl 26.1.21.32__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 (92) hide show
  1. persona_dsl-26.1.21.32/MANIFEST.in +1 -0
  2. persona_dsl-26.1.21.32/PKG-INFO +233 -0
  3. persona_dsl-26.1.21.32/README.md +196 -0
  4. persona_dsl-26.1.21.32/pyproject.toml +91 -0
  5. persona_dsl-26.1.21.32/setup.cfg +4 -0
  6. persona_dsl-26.1.21.32/src/persona_dsl/__init__.py +35 -0
  7. persona_dsl-26.1.21.32/src/persona_dsl/components/action.py +10 -0
  8. persona_dsl-26.1.21.32/src/persona_dsl/components/base_step.py +251 -0
  9. persona_dsl-26.1.21.32/src/persona_dsl/components/combined_step.py +68 -0
  10. persona_dsl-26.1.21.32/src/persona_dsl/components/expectation.py +10 -0
  11. persona_dsl-26.1.21.32/src/persona_dsl/components/fact.py +10 -0
  12. persona_dsl-26.1.21.32/src/persona_dsl/components/goal.py +10 -0
  13. persona_dsl-26.1.21.32/src/persona_dsl/components/ops.py +7 -0
  14. persona_dsl-26.1.21.32/src/persona_dsl/components/step.py +75 -0
  15. persona_dsl-26.1.21.32/src/persona_dsl/expectations/generic/__init__.py +15 -0
  16. persona_dsl-26.1.21.32/src/persona_dsl/expectations/generic/contains_item.py +19 -0
  17. persona_dsl-26.1.21.32/src/persona_dsl/expectations/generic/contains_the_text.py +15 -0
  18. persona_dsl-26.1.21.32/src/persona_dsl/expectations/generic/has_entries.py +21 -0
  19. persona_dsl-26.1.21.32/src/persona_dsl/expectations/generic/is_equal.py +24 -0
  20. persona_dsl-26.1.21.32/src/persona_dsl/expectations/generic/is_greater_than.py +18 -0
  21. persona_dsl-26.1.21.32/src/persona_dsl/expectations/generic/path_equal.py +27 -0
  22. persona_dsl-26.1.21.32/src/persona_dsl/expectations/web/__init__.py +5 -0
  23. persona_dsl-26.1.21.32/src/persona_dsl/expectations/web/is_displayed.py +13 -0
  24. persona_dsl-26.1.21.32/src/persona_dsl/expectations/web/matches_aria_snapshot.py +222 -0
  25. persona_dsl-26.1.21.32/src/persona_dsl/expectations/web/matches_screenshot.py +160 -0
  26. persona_dsl-26.1.21.32/src/persona_dsl/generators/__init__.py +5 -0
  27. persona_dsl-26.1.21.32/src/persona_dsl/generators/api_generator.py +423 -0
  28. persona_dsl-26.1.21.32/src/persona_dsl/generators/cli.py +431 -0
  29. persona_dsl-26.1.21.32/src/persona_dsl/generators/page_generator.py +1140 -0
  30. persona_dsl-26.1.21.32/src/persona_dsl/ops/api/__init__.py +5 -0
  31. persona_dsl-26.1.21.32/src/persona_dsl/ops/api/json_as.py +104 -0
  32. persona_dsl-26.1.21.32/src/persona_dsl/ops/api/json_response.py +48 -0
  33. persona_dsl-26.1.21.32/src/persona_dsl/ops/api/send_request.py +41 -0
  34. persona_dsl-26.1.21.32/src/persona_dsl/ops/db/__init__.py +5 -0
  35. persona_dsl-26.1.21.32/src/persona_dsl/ops/db/execute_sql.py +22 -0
  36. persona_dsl-26.1.21.32/src/persona_dsl/ops/db/fetch_all.py +29 -0
  37. persona_dsl-26.1.21.32/src/persona_dsl/ops/db/fetch_one.py +22 -0
  38. persona_dsl-26.1.21.32/src/persona_dsl/ops/kafka/__init__.py +4 -0
  39. persona_dsl-26.1.21.32/src/persona_dsl/ops/kafka/message_in_topic.py +89 -0
  40. persona_dsl-26.1.21.32/src/persona_dsl/ops/kafka/send_message.py +35 -0
  41. persona_dsl-26.1.21.32/src/persona_dsl/ops/soap/__init__.py +4 -0
  42. persona_dsl-26.1.21.32/src/persona_dsl/ops/soap/call_operation.py +24 -0
  43. persona_dsl-26.1.21.32/src/persona_dsl/ops/soap/operation_result.py +24 -0
  44. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/__init__.py +37 -0
  45. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/aria_snapshot.py +87 -0
  46. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/click.py +30 -0
  47. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/current_path.py +17 -0
  48. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/element_attribute.py +24 -0
  49. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/element_is_visible.py +27 -0
  50. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/element_text.py +28 -0
  51. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/elements_count.py +42 -0
  52. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/fill.py +41 -0
  53. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/generate_page_object.py +118 -0
  54. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/input_value.py +23 -0
  55. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/navigate.py +52 -0
  56. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/press_key.py +37 -0
  57. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/rich_aria_snapshot.py +159 -0
  58. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/screenshot.py +68 -0
  59. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/table_data.py +43 -0
  60. persona_dsl-26.1.21.32/src/persona_dsl/ops/web/wait_for_navigation.py +23 -0
  61. persona_dsl-26.1.21.32/src/persona_dsl/pages/__init__.py +133 -0
  62. persona_dsl-26.1.21.32/src/persona_dsl/pages/elements.py +998 -0
  63. persona_dsl-26.1.21.32/src/persona_dsl/pages/page.py +44 -0
  64. persona_dsl-26.1.21.32/src/persona_dsl/pages/virtual_page.py +94 -0
  65. persona_dsl-26.1.21.32/src/persona_dsl/persona.py +125 -0
  66. persona_dsl-26.1.21.32/src/persona_dsl/pytest_plugin.py +1230 -0
  67. persona_dsl-26.1.21.32/src/persona_dsl/runtime/dist/persona_bundle.js +1077 -0
  68. persona_dsl-26.1.21.32/src/persona_dsl/skills/__init__.py +7 -0
  69. persona_dsl-26.1.21.32/src/persona_dsl/skills/core/base.py +41 -0
  70. persona_dsl-26.1.21.32/src/persona_dsl/skills/core/skill_definition.py +30 -0
  71. persona_dsl-26.1.21.32/src/persona_dsl/skills/use_api.py +251 -0
  72. persona_dsl-26.1.21.32/src/persona_dsl/skills/use_browser.py +78 -0
  73. persona_dsl-26.1.21.32/src/persona_dsl/skills/use_database.py +129 -0
  74. persona_dsl-26.1.21.32/src/persona_dsl/skills/use_kafka.py +135 -0
  75. persona_dsl-26.1.21.32/src/persona_dsl/skills/use_soap.py +66 -0
  76. persona_dsl-26.1.21.32/src/persona_dsl/utils/__init__.py +0 -0
  77. persona_dsl-26.1.21.32/src/persona_dsl/utils/artifacts.py +22 -0
  78. persona_dsl-26.1.21.32/src/persona_dsl/utils/config.py +54 -0
  79. persona_dsl-26.1.21.32/src/persona_dsl/utils/data_providers.py +159 -0
  80. persona_dsl-26.1.21.32/src/persona_dsl/utils/decorators.py +80 -0
  81. persona_dsl-26.1.21.32/src/persona_dsl/utils/metrics.py +69 -0
  82. persona_dsl-26.1.21.32/src/persona_dsl/utils/naming.py +14 -0
  83. persona_dsl-26.1.21.32/src/persona_dsl/utils/path.py +202 -0
  84. persona_dsl-26.1.21.32/src/persona_dsl/utils/retry.py +51 -0
  85. persona_dsl-26.1.21.32/src/persona_dsl/utils/taas_integration.py +124 -0
  86. persona_dsl-26.1.21.32/src/persona_dsl/utils/waits.py +112 -0
  87. persona_dsl-26.1.21.32/src/persona_dsl.egg-info/PKG-INFO +233 -0
  88. persona_dsl-26.1.21.32/src/persona_dsl.egg-info/SOURCES.txt +90 -0
  89. persona_dsl-26.1.21.32/src/persona_dsl.egg-info/dependency_links.txt +1 -0
  90. persona_dsl-26.1.21.32/src/persona_dsl.egg-info/entry_points.txt +6 -0
  91. persona_dsl-26.1.21.32/src/persona_dsl.egg-info/requires.txt +31 -0
  92. persona_dsl-26.1.21.32/src/persona_dsl.egg-info/top_level.txt +1 -0
@@ -0,0 +1 @@
1
+ recursive-include src/persona_dsl/runtime/dist *.js
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.4
2
+ Name: persona-dsl
3
+ Version: 26.1.21.32
4
+ Summary: Persona DSL - Framework for implementing Screenplay pattern in Python tests
5
+ Requires-Python: >=3.9
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: playwright==1.55.0
8
+ Requires-Dist: pytest
9
+ Requires-Dist: pytest-cov
10
+ Requires-Dist: allure-pytest
11
+ Requires-Dist: python-dotenv
12
+ Requires-Dist: pyyaml
13
+ Requires-Dist: pydantic<3,>=2
14
+ Requires-Dist: requests
15
+ Requires-Dist: pyhamcrest
16
+ Requires-Dist: redis
17
+ Requires-Dist: Faker
18
+ Requires-Dist: pillow
19
+ Requires-Dist: zeep
20
+ Requires-Dist: pg8000
21
+ Requires-Dist: oracledb
22
+ Requires-Dist: kafka-python
23
+ Requires-Dist: Unidecode>=1.3
24
+ Requires-Dist: black
25
+ Provides-Extra: dev
26
+ Requires-Dist: black; extra == "dev"
27
+ Requires-Dist: ruff; extra == "dev"
28
+ Requires-Dist: mypy; extra == "dev"
29
+ Requires-Dist: pytest-cov; extra == "dev"
30
+ Requires-Dist: pre-commit; extra == "dev"
31
+ Requires-Dist: types-requests; extra == "dev"
32
+ Requires-Dist: types-PyYAML; extra == "dev"
33
+ Requires-Dist: types-redis; extra == "dev"
34
+ Requires-Dist: pytest-asyncio; extra == "dev"
35
+ Requires-Dist: pytest-timeout; extra == "dev"
36
+ Requires-Dist: pytest-xdist; extra == "dev"
37
+
38
+ # persona-dsl: Фреймворк для автотестов на Python
39
+
40
+ `persona-dsl` — это современная библиотека для написания **E2E** и **API** автотестов, реализующая паттерн **Screenplay**.
41
+ Она предоставляет выразительный язык для описания сценариев, управляет браузером (через Playwright) и автоматически генерирует детальные отчеты Allure.
42
+
43
+ ## 📦 Установка
44
+
45
+ ```bash
46
+ pip install persona-dsl
47
+ python -m playwright install --with-deps
48
+ ```
49
+
50
+ ---
51
+
52
+ ## 🚀 Быстрый старт
53
+
54
+ ### 1. Описание страницы (Page Object)
55
+
56
+ В `persona-dsl` используется **Универсальная Архитектура Элементов**.
57
+ Основной класс `Page` сам является элементом-контейнером. Вложенные элементы добавляются через `add_element`.
58
+
59
+ ```python
60
+ # pages/login_page.py
61
+ from persona_dsl.pages import Page
62
+ from persona_dsl.pages.elements import Input, Button
63
+
64
+ class LoginPage(Page):
65
+ def __init__(self):
66
+ super().__init__()
67
+ # Имя атрибута (self.username) будет использовано как имя элемента в отчетах
68
+ self.username = self.add_element(Input(xpath="//input[@id='user']", name="Логин"))
69
+ self.password = self.add_element(Input(xpath="//input[@id='pass']", name="Пароль"))
70
+ self.submit = self.add_element(Button(xpath="//button[@type='submit']", name="Вход"))
71
+ ```
72
+
73
+ ### 2. Написание теста
74
+
75
+ Тесты пишутся в стиле "Persona делает действия":
76
+
77
+ ```python
78
+ # tests/test_login.py
79
+ import pytest
80
+ from persona_dsl.ops.web import NavigateTo, Fill, Click
81
+ from persona_dsl.facts.web import CurrentPath
82
+ from persona_dsl.expectations.web import IsEqualTo
83
+ from pages.login_page import LoginPage
84
+
85
+ def test_login_flow(persona):
86
+ login_page = LoginPage()
87
+
88
+ # 1. Действия (Actions)
89
+ persona.make(
90
+ NavigateTo("/login"),
91
+ Fill(login_page.username, "admin"),
92
+ Fill(login_page.password, "secret"),
93
+ Click(login_page.submit)
94
+ )
95
+
96
+ # 2. Проверка (Verification)
97
+ # Получаем Факт (CurrentPath) и проверяем Ожидание (IsEqualTo)
98
+ current_path = persona.get(CurrentPath())
99
+ persona.check(current_path, IsEqualTo("/dashboard"))
100
+ ```
101
+
102
+ ---
103
+
104
+ ## 🏗 Архитектура
105
+
106
+ ### 1. Ключевые компоненты (Persona Core)
107
+
108
+ | Компонент | Назначение | Пример |
109
+ |-----------|------------|--------|
110
+ | **Persona** | Исполнитель. Хранит состояние и навыки. | `persona.make(...)` |
111
+ | **Skill** | "Навык". Дает доступ к инструментам. | `UseBrowser`, `UseAPI`, `UseDB` |
112
+ | **Ops** | Атомарная операция. Работает со Skill. | `Click`, `HttpRequest`, `ExecuteSQL` |
113
+ | **Step** | Бизнес-шаг. Группирует Ops. | `LoginStep`, `CreateOrder` |
114
+ | **Fact** | Запрос состояния (без изменений). | `CurrentPath`, `ElementText` |
115
+ | **Expectation** | Проверка значения. | `IsEqualTo`, `ContainsText` |
116
+
117
+ ### 2. Универсальные Элементы (New!)
118
+
119
+ Больше нет разделения на `Element` и `ElementContainer`. Любой элемент может содержать другие элементы.
120
+
121
+ * **`element.add_element(...)`**: Регистрирует дочерний элемент.
122
+ * **Иерархия**: `Page -> Container -> Element`.
123
+ * **Локаторы**: Строятся автоматически по цепочке родителей.
124
+
125
+ ### 3. Генераторный подход
126
+ Все шаги (`Step`, `CombinedStep`) — это генераторы, которые "выдают" (`yield`) операции для исполнения Персоной. Это позволяет `persona-dsl` перехватывать каждый шаг, логировать его в Allure и обрабатывать ошибки.
127
+
128
+ ---
129
+
130
+ ## 🛠 Инструменты и Утилиты
131
+
132
+ ### Генерация Page Objects
133
+ Не пишите селекторы вручную. Используйте генератор:
134
+
135
+ ```bash
136
+ # Снять ARIA-снапшот и сгенерировать класс страницы
137
+ persona-page-gen --url http://localhost:8080 --output pages/home.py
138
+ ```
139
+
140
+ ### Генерация API клиентов
141
+ ```bash
142
+ # Генерация из OpenAPI/Swagger
143
+ persona-api-gen --url http://api.example.com/openapi.json --output skills/my_api.py
144
+ ```
145
+
146
+ ### Запуск тестов
147
+
148
+ Тесты запускаются стандартной командой pytest:
149
+
150
+ ```bash
151
+ pytest --env=dev tests/
152
+ ```
153
+
154
+ ---
155
+
156
+ ## ⚙️ Конфигурация
157
+
158
+ ### `conftest.py`
159
+ Декларативное описание навыков и ролей:
160
+ ```python
161
+ PERSONA_SKILLS = [BaseSkill.BROWSER, BaseSkill.API]
162
+ ```
163
+
164
+ ### `config/{env}.yaml`
165
+ Параметры окружения (dev, test, prod). Выбирается через `--env=test`.
166
+
167
+ ### Примеры конфигурации
168
+
169
+ Ниже представлен **полный справочник** всех возможных настроек.
170
+ Большинство параметров унифицированы и работают идентично для **Локального** запуска и **Selenoid**.
171
+
172
+ #### Полный справочник (Global Reference)
173
+
174
+ Этот конфиг покрывает все возможности фреймворка. Неиспользуемые параметры можно опускать.
175
+
176
+ ```yaml
177
+ skills:
178
+ browser:
179
+ default:
180
+ base_url: "https://my-app.test" # URL должен быть внутри навыка
181
+
182
+ # --- Базовые настройки (Basic) ---
183
+ type: chromium # Тип: chromium, firefox, webkit, sberbrowser, msedge
184
+ headless: true # true = без UI (в контейнере тоже работает)
185
+ channel: chrome # (Optional) Канал: chrome, msedge, chrome-beta
186
+ executable_path: "" # (Optional) Кастомный путь к бинарнику
187
+ version: "128.0" # (Optional) Версия (для Selenoid или скачивания)
188
+
189
+ # --- Размеры и Тайминги (Dimensions & Timings) ---
190
+ viewport:
191
+ width: 1920
192
+ height: 1080 # Всегда используйте многострочный формат для читаемости
193
+ slow_mo: 50.0 # Задержка между действиями (мс)
194
+ default_timeout: 30000.0 # Таймаут поиска элементов (мс)
195
+ default_navigation_timeout: 30000.0 # Таймаут загрузки (мс)
196
+
197
+ # --- Аргументы и Флаги (Arguments) ---
198
+ # Применяются и локально, и удаленно (через goog:chromeOptions)
199
+ no_sandbox: true # --no-sandbox
200
+ ignore_https_errors: true # --ignore-certificate-errors
201
+ disable_features: # --disable-features=...
202
+ - SidePanel
203
+ - SberWhatsNew
204
+ args: # Дополнительные аргументы
205
+ - "--start-maximized"
206
+ - "--disable-notifications"
207
+ - "--disable-gpu"
208
+
209
+ # --- Удаленный запуск (Remote / Selenoid) ---
210
+ # Если URL задан, тесты пойдут в облако/контейнер
211
+ selenoid_url: "http://selenoid.company.com:4444"
212
+
213
+ session_retries: 3 # Повторные попытки при ошибке создания сессии
214
+ session_timeout: 60.0 # Таймаут ожидания слота (сек)
215
+
216
+ selenoid_options:
217
+ enableVNC: true # Включить Live-просмотр
218
+ enableVideo: false # Включить запись видео
219
+ # name/videoName проставляются автоматически
220
+ ```
221
+
222
+
223
+
224
+ ---
225
+
226
+ ## 📊 Отчетность (Allure + TaaS)
227
+
228
+ Фреймворк автоматически:
229
+ 1. Создает вложенные **Allure Steps** для каждого действия.
230
+ 2. Прикрепляет **Скриншоты** и **Page Source** при падении.
231
+ 3. Логирует **HTTP запросы/ответы** (если включено).
232
+ 4. Интегрируется с платформой **TaaS** (Test as a Service) для аналитики.
233
+
@@ -0,0 +1,196 @@
1
+ # persona-dsl: Фреймворк для автотестов на Python
2
+
3
+ `persona-dsl` — это современная библиотека для написания **E2E** и **API** автотестов, реализующая паттерн **Screenplay**.
4
+ Она предоставляет выразительный язык для описания сценариев, управляет браузером (через Playwright) и автоматически генерирует детальные отчеты Allure.
5
+
6
+ ## 📦 Установка
7
+
8
+ ```bash
9
+ pip install persona-dsl
10
+ python -m playwright install --with-deps
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 🚀 Быстрый старт
16
+
17
+ ### 1. Описание страницы (Page Object)
18
+
19
+ В `persona-dsl` используется **Универсальная Архитектура Элементов**.
20
+ Основной класс `Page` сам является элементом-контейнером. Вложенные элементы добавляются через `add_element`.
21
+
22
+ ```python
23
+ # pages/login_page.py
24
+ from persona_dsl.pages import Page
25
+ from persona_dsl.pages.elements import Input, Button
26
+
27
+ class LoginPage(Page):
28
+ def __init__(self):
29
+ super().__init__()
30
+ # Имя атрибута (self.username) будет использовано как имя элемента в отчетах
31
+ self.username = self.add_element(Input(xpath="//input[@id='user']", name="Логин"))
32
+ self.password = self.add_element(Input(xpath="//input[@id='pass']", name="Пароль"))
33
+ self.submit = self.add_element(Button(xpath="//button[@type='submit']", name="Вход"))
34
+ ```
35
+
36
+ ### 2. Написание теста
37
+
38
+ Тесты пишутся в стиле "Persona делает действия":
39
+
40
+ ```python
41
+ # tests/test_login.py
42
+ import pytest
43
+ from persona_dsl.ops.web import NavigateTo, Fill, Click
44
+ from persona_dsl.facts.web import CurrentPath
45
+ from persona_dsl.expectations.web import IsEqualTo
46
+ from pages.login_page import LoginPage
47
+
48
+ def test_login_flow(persona):
49
+ login_page = LoginPage()
50
+
51
+ # 1. Действия (Actions)
52
+ persona.make(
53
+ NavigateTo("/login"),
54
+ Fill(login_page.username, "admin"),
55
+ Fill(login_page.password, "secret"),
56
+ Click(login_page.submit)
57
+ )
58
+
59
+ # 2. Проверка (Verification)
60
+ # Получаем Факт (CurrentPath) и проверяем Ожидание (IsEqualTo)
61
+ current_path = persona.get(CurrentPath())
62
+ persona.check(current_path, IsEqualTo("/dashboard"))
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 🏗 Архитектура
68
+
69
+ ### 1. Ключевые компоненты (Persona Core)
70
+
71
+ | Компонент | Назначение | Пример |
72
+ |-----------|------------|--------|
73
+ | **Persona** | Исполнитель. Хранит состояние и навыки. | `persona.make(...)` |
74
+ | **Skill** | "Навык". Дает доступ к инструментам. | `UseBrowser`, `UseAPI`, `UseDB` |
75
+ | **Ops** | Атомарная операция. Работает со Skill. | `Click`, `HttpRequest`, `ExecuteSQL` |
76
+ | **Step** | Бизнес-шаг. Группирует Ops. | `LoginStep`, `CreateOrder` |
77
+ | **Fact** | Запрос состояния (без изменений). | `CurrentPath`, `ElementText` |
78
+ | **Expectation** | Проверка значения. | `IsEqualTo`, `ContainsText` |
79
+
80
+ ### 2. Универсальные Элементы (New!)
81
+
82
+ Больше нет разделения на `Element` и `ElementContainer`. Любой элемент может содержать другие элементы.
83
+
84
+ * **`element.add_element(...)`**: Регистрирует дочерний элемент.
85
+ * **Иерархия**: `Page -> Container -> Element`.
86
+ * **Локаторы**: Строятся автоматически по цепочке родителей.
87
+
88
+ ### 3. Генераторный подход
89
+ Все шаги (`Step`, `CombinedStep`) — это генераторы, которые "выдают" (`yield`) операции для исполнения Персоной. Это позволяет `persona-dsl` перехватывать каждый шаг, логировать его в Allure и обрабатывать ошибки.
90
+
91
+ ---
92
+
93
+ ## 🛠 Инструменты и Утилиты
94
+
95
+ ### Генерация Page Objects
96
+ Не пишите селекторы вручную. Используйте генератор:
97
+
98
+ ```bash
99
+ # Снять ARIA-снапшот и сгенерировать класс страницы
100
+ persona-page-gen --url http://localhost:8080 --output pages/home.py
101
+ ```
102
+
103
+ ### Генерация API клиентов
104
+ ```bash
105
+ # Генерация из OpenAPI/Swagger
106
+ persona-api-gen --url http://api.example.com/openapi.json --output skills/my_api.py
107
+ ```
108
+
109
+ ### Запуск тестов
110
+
111
+ Тесты запускаются стандартной командой pytest:
112
+
113
+ ```bash
114
+ pytest --env=dev tests/
115
+ ```
116
+
117
+ ---
118
+
119
+ ## ⚙️ Конфигурация
120
+
121
+ ### `conftest.py`
122
+ Декларативное описание навыков и ролей:
123
+ ```python
124
+ PERSONA_SKILLS = [BaseSkill.BROWSER, BaseSkill.API]
125
+ ```
126
+
127
+ ### `config/{env}.yaml`
128
+ Параметры окружения (dev, test, prod). Выбирается через `--env=test`.
129
+
130
+ ### Примеры конфигурации
131
+
132
+ Ниже представлен **полный справочник** всех возможных настроек.
133
+ Большинство параметров унифицированы и работают идентично для **Локального** запуска и **Selenoid**.
134
+
135
+ #### Полный справочник (Global Reference)
136
+
137
+ Этот конфиг покрывает все возможности фреймворка. Неиспользуемые параметры можно опускать.
138
+
139
+ ```yaml
140
+ skills:
141
+ browser:
142
+ default:
143
+ base_url: "https://my-app.test" # URL должен быть внутри навыка
144
+
145
+ # --- Базовые настройки (Basic) ---
146
+ type: chromium # Тип: chromium, firefox, webkit, sberbrowser, msedge
147
+ headless: true # true = без UI (в контейнере тоже работает)
148
+ channel: chrome # (Optional) Канал: chrome, msedge, chrome-beta
149
+ executable_path: "" # (Optional) Кастомный путь к бинарнику
150
+ version: "128.0" # (Optional) Версия (для Selenoid или скачивания)
151
+
152
+ # --- Размеры и Тайминги (Dimensions & Timings) ---
153
+ viewport:
154
+ width: 1920
155
+ height: 1080 # Всегда используйте многострочный формат для читаемости
156
+ slow_mo: 50.0 # Задержка между действиями (мс)
157
+ default_timeout: 30000.0 # Таймаут поиска элементов (мс)
158
+ default_navigation_timeout: 30000.0 # Таймаут загрузки (мс)
159
+
160
+ # --- Аргументы и Флаги (Arguments) ---
161
+ # Применяются и локально, и удаленно (через goog:chromeOptions)
162
+ no_sandbox: true # --no-sandbox
163
+ ignore_https_errors: true # --ignore-certificate-errors
164
+ disable_features: # --disable-features=...
165
+ - SidePanel
166
+ - SberWhatsNew
167
+ args: # Дополнительные аргументы
168
+ - "--start-maximized"
169
+ - "--disable-notifications"
170
+ - "--disable-gpu"
171
+
172
+ # --- Удаленный запуск (Remote / Selenoid) ---
173
+ # Если URL задан, тесты пойдут в облако/контейнер
174
+ selenoid_url: "http://selenoid.company.com:4444"
175
+
176
+ session_retries: 3 # Повторные попытки при ошибке создания сессии
177
+ session_timeout: 60.0 # Таймаут ожидания слота (сек)
178
+
179
+ selenoid_options:
180
+ enableVNC: true # Включить Live-просмотр
181
+ enableVideo: false # Включить запись видео
182
+ # name/videoName проставляются автоматически
183
+ ```
184
+
185
+
186
+
187
+ ---
188
+
189
+ ## 📊 Отчетность (Allure + TaaS)
190
+
191
+ Фреймворк автоматически:
192
+ 1. Создает вложенные **Allure Steps** для каждого действия.
193
+ 2. Прикрепляет **Скриншоты** и **Page Source** при падении.
194
+ 3. Логирует **HTTP запросы/ответы** (если включено).
195
+ 4. Интегрируется с платформой **TaaS** (Test as a Service) для аналитики.
196
+
@@ -0,0 +1,91 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "persona-dsl"
7
+ version = "26.01.21.032"
8
+ description = "Persona DSL - Framework for implementing Screenplay pattern in Python tests"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ dependencies = [
12
+ "playwright==1.55.0",
13
+ "pytest",
14
+ "pytest-cov",
15
+ "allure-pytest",
16
+ "python-dotenv",
17
+ "pyyaml",
18
+ "pydantic>=2,<3",
19
+ "requests",
20
+ "pyhamcrest",
21
+ "redis",
22
+ "Faker",
23
+ "pillow",
24
+ "zeep",
25
+ "pg8000",
26
+ "oracledb",
27
+ "kafka-python",
28
+ "Unidecode>=1.3",
29
+ "black",
30
+ ]
31
+ [project.optional-dependencies]
32
+ dev = [
33
+ "black",
34
+ "ruff",
35
+ "mypy",
36
+ "pytest-cov",
37
+ "pre-commit",
38
+ "types-requests",
39
+ "types-PyYAML",
40
+ "types-redis",
41
+ "pytest-asyncio",
42
+ "pytest-timeout",
43
+ "pytest-xdist",
44
+ ]
45
+
46
+ [project.entry-points.pytest11]
47
+ persona_dsl = "persona_dsl.pytest_plugin"
48
+
49
+ [project.scripts]
50
+ persona-page-gen = "persona_dsl.generators.cli:page_main"
51
+ persona-api-gen = "persona_dsl.generators.cli:api_main"
52
+
53
+ [tool.setuptools.packages.find]
54
+ where = ["src"]
55
+
56
+ [tool.coverage.run]
57
+ source = ["src/persona_dsl"]
58
+ omit = [
59
+ # --- Компоненты, сложные для юнит-тестирования (снапшоты) ---
60
+ "src/persona_dsl/expectations/web/matches_screenshot.py",
61
+ "src/persona_dsl/expectations/web/matches_aria_snapshot.py",
62
+ # --- Файлы без исполняемой логики (базовые классы, Enum'ы, импорты) ---
63
+ "src/persona_dsl/__init__.py",
64
+ "src/persona_dsl/skills/__init__.py",
65
+ "src/persona_dsl/enums.py",
66
+ "src/persona_dsl/skill_id.py",
67
+ "src/persona_dsl/expectation.py",
68
+ ]
69
+ parallel = true
70
+
71
+ [tool.coverage.report]
72
+ show_missing = true
73
+
74
+ [tool.mypy]
75
+ python_version = "3.12"
76
+ warn_unused_ignores = true
77
+ warn_redundant_casts = true
78
+ disallow_untyped_defs = true
79
+ disallow_incomplete_defs = true
80
+ no_implicit_optional = true
81
+ strict_equality = true
82
+ ignore_missing_imports = true
83
+
84
+ [[tool.mypy.overrides]]
85
+ module = "persona_dsl.*"
86
+ check_untyped_defs = true
87
+
88
+ [[tool.mypy.overrides]]
89
+ module = "tests.*"
90
+ ignore_errors = true
91
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,35 @@
1
+ from .components.action import Action
2
+ from .utils.decorators import data_driven, tag, parametrize_simple
3
+ from .persona import BaseRole
4
+ from .skills.core.skill_definition import BaseSkill
5
+ from .components.expectation import Expectation
6
+ from .components.fact import Fact
7
+ from .components.goal import Goal
8
+ from .persona import Persona
9
+ from .skills.core.skill_definition import SkillId
10
+ from .utils.waits import wait_until
11
+ from .skills.core.base import Skill
12
+ from .skills import UseAPI, UseBrowser, UseDatabase, UseKafka, UseSOAP
13
+ from .components.step import Step
14
+
15
+ __all__ = [
16
+ "Action",
17
+ "Expectation",
18
+ "Goal",
19
+ "Persona",
20
+ "Fact",
21
+ "SkillId",
22
+ "Step",
23
+ "data_driven",
24
+ "tag",
25
+ "parametrize_simple",
26
+ "BaseRole",
27
+ "BaseSkill",
28
+ "Skill",
29
+ "wait_until",
30
+ "UseAPI",
31
+ "UseBrowser",
32
+ "UseDatabase",
33
+ "UseKafka",
34
+ "UseSOAP",
35
+ ]
@@ -0,0 +1,10 @@
1
+ from .step import Step
2
+
3
+
4
+ class Action(Step):
5
+ """
6
+ Алиас для Step, предназначенный для story-стиля.
7
+ Не содержит собственной логики.
8
+ """
9
+
10
+ pass