codemie-test-harness 0.1.168__py3-none-any.whl → 0.1.170__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.
Potentially problematic release.
This version of codemie-test-harness might be problematic. Click here for more details.
- codemie_test_harness/cli/cli.py +18 -74
- codemie_test_harness/cli/commands/assistant_cmd.py +104 -0
- codemie_test_harness/cli/commands/config_cmd.py +610 -20
- codemie_test_harness/cli/commands/workflow_cmd.py +64 -0
- codemie_test_harness/cli/constants.py +385 -6
- codemie_test_harness/cli/utils.py +9 -0
- codemie_test_harness/tests/test_data/assistant_test_data.py +197 -0
- codemie_test_harness/tests/test_data/project_management_test_data.py +1 -1
- codemie_test_harness/tests/ui/assistants/__init__.py +0 -0
- codemie_test_harness/tests/ui/assistants/test_create_assistant.py +408 -0
- codemie_test_harness/tests/ui/conftest.py +23 -3
- codemie_test_harness/tests/ui/pageobject/assistants/assistants_page.py +3 -4
- codemie_test_harness/tests/ui/pageobject/assistants/create_assistant_page.py +689 -0
- codemie_test_harness/tests/ui/pageobject/assistants/generate_with_ai_modal.py +367 -0
- codemie_test_harness/tests/ui/pageobject/base_page.py +2 -2
- codemie_test_harness/tests/ui/pytest.ini +18 -0
- codemie_test_harness/tests/ui/workflows/test_workflows.py +1 -1
- codemie_test_harness/tests/utils/credentials_manager.py +0 -15
- {codemie_test_harness-0.1.168.dist-info → codemie_test_harness-0.1.170.dist-info}/METADATA +2 -2
- {codemie_test_harness-0.1.168.dist-info → codemie_test_harness-0.1.170.dist-info}/RECORD +22 -14
- {codemie_test_harness-0.1.168.dist-info → codemie_test_harness-0.1.170.dist-info}/WHEEL +0 -0
- {codemie_test_harness-0.1.168.dist-info → codemie_test_harness-0.1.170.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Workflow CLI commands for executing and managing workflows."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
|
|
8
|
+
from codemie_test_harness.tests.utils.client_factory import get_client
|
|
9
|
+
from ..constants import CONSOLE
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@click.group(name="workflow")
|
|
13
|
+
def workflow_cmd():
|
|
14
|
+
"""Interact with CodeMie workflows."""
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@workflow_cmd.command(name="execute")
|
|
19
|
+
@click.option(
|
|
20
|
+
"--workflow-id",
|
|
21
|
+
required=True,
|
|
22
|
+
help="Workflow ID to execute",
|
|
23
|
+
)
|
|
24
|
+
@click.option(
|
|
25
|
+
"--user-input",
|
|
26
|
+
"-i",
|
|
27
|
+
default="",
|
|
28
|
+
help="User input for the workflow execution (optional)",
|
|
29
|
+
)
|
|
30
|
+
def execute_cmd(
|
|
31
|
+
workflow_id: str,
|
|
32
|
+
user_input: str,
|
|
33
|
+
):
|
|
34
|
+
"""Execute a workflow.
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
codemie-test-harness workflow execute --workflow-id "wf_123"
|
|
38
|
+
codemie-test-harness workflow execute --workflow-id "wf_123" --user-input "process this data"
|
|
39
|
+
"""
|
|
40
|
+
try:
|
|
41
|
+
client = get_client()
|
|
42
|
+
|
|
43
|
+
CONSOLE.print(f"[yellow]Executing workflow {workflow_id}...[/yellow]")
|
|
44
|
+
if user_input:
|
|
45
|
+
CONSOLE.print(f"[blue]User input: {user_input}[/blue]")
|
|
46
|
+
|
|
47
|
+
# Execute workflow
|
|
48
|
+
response = client.workflows.run(workflow_id=workflow_id, user_input=user_input)
|
|
49
|
+
|
|
50
|
+
# Display response
|
|
51
|
+
CONSOLE.print("[green]Workflow execution started successfully![/green]")
|
|
52
|
+
|
|
53
|
+
if hasattr(response, "execution_id"):
|
|
54
|
+
CONSOLE.print(f"[cyan]Execution ID: {response.execution_id}[/cyan]")
|
|
55
|
+
|
|
56
|
+
if hasattr(response, "status"):
|
|
57
|
+
CONSOLE.print(f"[cyan]Status: {response.status}[/cyan]")
|
|
58
|
+
|
|
59
|
+
# Display the full response for debugging
|
|
60
|
+
CONSOLE.print(f"[dim]Response: {response}[/dim]")
|
|
61
|
+
|
|
62
|
+
except Exception as e:
|
|
63
|
+
CONSOLE.print(f"[red]Error executing workflow: {e}[/red]")
|
|
64
|
+
raise click.ClickException(str(e))
|
|
@@ -12,13 +12,16 @@ CONFIG_FILE = CONFIG_DIR / "test-harness.json"
|
|
|
12
12
|
KEY_AUTH_SERVER_URL = "AUTH_SERVER_URL"
|
|
13
13
|
KEY_AUTH_CLIENT_ID = "AUTH_CLIENT_ID"
|
|
14
14
|
KEY_AUTH_CLIENT_SECRET = "AUTH_CLIENT_SECRET"
|
|
15
|
+
KEY_AUTH_PASSWORD = "AUTH_PASSWORD"
|
|
16
|
+
KEY_AUTH_USERNAME = "AUTH_USERNAME"
|
|
15
17
|
KEY_AUTH_REALM_NAME = "AUTH_REALM_NAME"
|
|
16
18
|
KEY_CODEMIE_API_DOMAIN = "CODEMIE_API_DOMAIN"
|
|
17
19
|
KEY_MARKS = "PYTEST_MARKS"
|
|
18
20
|
KEY_XDIST_N = "PYTEST_N"
|
|
19
21
|
KEY_RERUNS = "PYTEST_RERUNS"
|
|
20
22
|
|
|
21
|
-
#
|
|
23
|
+
# === COMPLETE INTEGRATION CREDENTIALS KEYS ===
|
|
24
|
+
# Version Control Systems (GitLab, GitHub)
|
|
22
25
|
KEY_GIT_ENV = "GIT_ENV" # e.g. gitlab or github
|
|
23
26
|
# GitLab
|
|
24
27
|
KEY_GITLAB_URL = "GITLAB_URL"
|
|
@@ -29,14 +32,115 @@ KEY_GITLAB_PROJECT_ID = "GITLAB_PROJECT_ID"
|
|
|
29
32
|
KEY_GITHUB_URL = "GITHUB_URL"
|
|
30
33
|
KEY_GITHUB_TOKEN = "GITHUB_TOKEN"
|
|
31
34
|
KEY_GITHUB_PROJECT = "GITHUB_PROJECT"
|
|
32
|
-
|
|
35
|
+
|
|
36
|
+
# Project Management (JIRA, Confluence)
|
|
37
|
+
# JIRA Server
|
|
33
38
|
KEY_JIRA_URL = "JIRA_URL"
|
|
34
39
|
KEY_JIRA_TOKEN = "JIRA_TOKEN"
|
|
35
|
-
KEY_JQL = "
|
|
36
|
-
#
|
|
40
|
+
KEY_JQL = "JIRA_JQL"
|
|
41
|
+
# JIRA Cloud
|
|
42
|
+
KEY_JIRA_CLOUD_URL = "JIRA_CLOUD_URL"
|
|
43
|
+
KEY_JIRA_CLOUD_EMAIL = "JIRA_CLOUD_EMAIL"
|
|
44
|
+
KEY_JIRA_CLOUD_TOKEN = "JIRA_CLOUD_TOKEN"
|
|
45
|
+
KEY_JIRA_CLOUD_JQL = "JIRA_CLOUD_JQL"
|
|
46
|
+
# Confluence Server
|
|
37
47
|
KEY_CONFLUENCE_URL = "CONFLUENCE_URL"
|
|
38
48
|
KEY_CONFLUENCE_TOKEN = "CONFLUENCE_TOKEN"
|
|
39
|
-
KEY_CQL = "
|
|
49
|
+
KEY_CQL = "CONFLUENCE_CQL"
|
|
50
|
+
# Confluence Cloud
|
|
51
|
+
KEY_CONFLUENCE_CLOUD_URL = "CONFLUENCE_CLOUD_URL"
|
|
52
|
+
KEY_CONFLUENCE_CLOUD_EMAIL = "CONFLUENCE_CLOUD_EMAIL"
|
|
53
|
+
KEY_CONFLUENCE_CLOUD_TOKEN = "CONFLUENCE_CLOUD_TOKEN"
|
|
54
|
+
KEY_CONFLUENCE_CLOUD_CQL = "CONFLUENCE_CLOUD_CQL"
|
|
55
|
+
|
|
56
|
+
# Cloud Providers (AWS, Azure, GCP)
|
|
57
|
+
# AWS
|
|
58
|
+
KEY_AWS_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID"
|
|
59
|
+
KEY_AWS_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY"
|
|
60
|
+
KEY_AWS_REGION = "AWS_REGION"
|
|
61
|
+
KEY_AWS_SESSION_TOKEN = "AWS_SESSION_TOKEN"
|
|
62
|
+
# Azure
|
|
63
|
+
KEY_AZURE_CLIENT_ID = "AZURE_CLIENT_ID"
|
|
64
|
+
KEY_AZURE_CLIENT_SECRET = "AZURE_CLIENT_SECRET"
|
|
65
|
+
KEY_AZURE_TENANT_ID = "AZURE_TENANT_ID"
|
|
66
|
+
KEY_AZURE_SUBSCRIPTION_ID = "AZURE_SUBSCRIPTION_ID"
|
|
67
|
+
# GCP
|
|
68
|
+
KEY_GCP_SA_KEY_BASE64 = "GCP_SA_KEY_BASE64"
|
|
69
|
+
|
|
70
|
+
# Development Tools (Azure DevOps, ServiceNow, Keycloak, SonarQube)
|
|
71
|
+
# Azure DevOps
|
|
72
|
+
KEY_AZURE_DEVOPS_URL = "AZURE_DEVOPS_URL"
|
|
73
|
+
KEY_AZURE_DEVOPS_TOKEN = "AZURE_DEVOPS_TOKEN"
|
|
74
|
+
KEY_AZURE_DEVOPS_PROJECT_NAME = "AZURE_DEVOPS_PROJECT_NAME"
|
|
75
|
+
KEY_AZURE_DEVOPS_ORGANIZATION_NAME = "AZURE_DEVOPS_ORGANIZATION_NAME"
|
|
76
|
+
# ServiceNow
|
|
77
|
+
KEY_SERVICENOW_URL = "SERVICENOW_URL"
|
|
78
|
+
KEY_SERVICENOW_TOKEN = "SERVICENOW_TOKEN"
|
|
79
|
+
# Keycloak
|
|
80
|
+
KEY_KEYCLOAK_URL = "KEYCLOAK_URL"
|
|
81
|
+
KEY_KEYCLOAK_REALM = "KEYCLOAK_REALM"
|
|
82
|
+
KEY_KEYCLOAK_CLIENT_ID = "KEYCLOAK_CLIENT_ID"
|
|
83
|
+
KEY_KEYCLOAK_CLIENT_SECRET = "KEYCLOAK_CLIENT_SECRET"
|
|
84
|
+
# SonarQube Server
|
|
85
|
+
KEY_SONAR_URL = "SONAR_URL"
|
|
86
|
+
KEY_SONAR_TOKEN = "SONAR_TOKEN"
|
|
87
|
+
KEY_SONAR_PROJECT_KEY = "SONAR_PROJECT_KEY"
|
|
88
|
+
# SonarCloud
|
|
89
|
+
KEY_SONAR_CLOUD_URL = "SONAR_CLOUD_URL"
|
|
90
|
+
KEY_SONAR_CLOUD_TOKEN = "SONAR_CLOUD_TOKEN"
|
|
91
|
+
KEY_SONAR_CLOUD_PROJECT_KEY = "SONAR_CLOUD_PROJECT_KEY"
|
|
92
|
+
|
|
93
|
+
# Notifications (Email/Gmail, OAuth, Telegram)
|
|
94
|
+
# Email/Gmail
|
|
95
|
+
KEY_GMAIL_URL = "GMAIL_URL"
|
|
96
|
+
KEY_SMTP_USERNAME = "SMTP_USERNAME"
|
|
97
|
+
KEY_SMTP_PASSWORD = "SMTP_PASSWORD"
|
|
98
|
+
# OAuth
|
|
99
|
+
KEY_OAUTH_URL = "OAUTH_URL"
|
|
100
|
+
KEY_OAUTH_CLIENT_ID = "OAUTH_CLIENT_ID"
|
|
101
|
+
KEY_OAUTH_CLIENT_SECRET = "OAUTH_CLIENT_SECRET"
|
|
102
|
+
KEY_OAUTH_REFRESH_TOKEN = "OAUTH_REFRESH_TOKEN"
|
|
103
|
+
# Telegram
|
|
104
|
+
KEY_TELEGRAM_TOKEN = "TELEGRAM_TOKEN"
|
|
105
|
+
KEY_TELEGRAM_CHAT_ID = "TELEGRAM_CHAT_ID"
|
|
106
|
+
|
|
107
|
+
# Research Tools (Kubernetes, Report Portal, Elasticsearch)
|
|
108
|
+
# Kubernetes
|
|
109
|
+
KEY_KUBERNETES_URL = "KUBERNETES_URL"
|
|
110
|
+
KEY_KUBERNETES_TOKEN = "KUBERNETES_TOKEN"
|
|
111
|
+
# Report Portal
|
|
112
|
+
KEY_REPORT_PORTAL_URL = "REPORT_PORTAL_URL"
|
|
113
|
+
KEY_REPORT_PORTAL_API_KEY = "REPORT_PORTAL_API_KEY"
|
|
114
|
+
KEY_REPORT_PORTAL_PROJECT = "REPORT_PORTAL_PROJECT"
|
|
115
|
+
# Elasticsearch
|
|
116
|
+
KEY_ELASTICSEARCH_URL = "ELASTICSEARCH_URL"
|
|
117
|
+
KEY_ELASTICSEARCH_API_KEY_ID = "ELASTICSEARCH_API_KEY_ID"
|
|
118
|
+
KEY_ELASTICSEARCH_API_KEY = "ELASTICSEARCH_API_KEY"
|
|
119
|
+
|
|
120
|
+
# Data Management (SQL databases, LiteLLM)
|
|
121
|
+
# LiteLLM
|
|
122
|
+
KEY_LITE_LLM_API_KEY = "LITE_LLM_API_KEY"
|
|
123
|
+
# MySQL
|
|
124
|
+
KEY_MYSQL_DIALECT = "MYSQL_DIALECT"
|
|
125
|
+
KEY_MYSQL_URL = "MYSQL_URL"
|
|
126
|
+
KEY_MYSQL_PORT = "MYSQL_PORT"
|
|
127
|
+
KEY_MYSQL_DATABASE_NAME = "MYSQL_DATABASE_NAME"
|
|
128
|
+
KEY_MYSQL_USERNAME = "MYSQL_USERNAME"
|
|
129
|
+
KEY_MYSQL_PASSWORD = "MYSQL_PASSWORD"
|
|
130
|
+
# PostgreSQL
|
|
131
|
+
KEY_POSTGRES_DIALECT = "POSTGRES_DIALECT"
|
|
132
|
+
KEY_POSTGRES_URL = "POSTGRES_URL"
|
|
133
|
+
KEY_POSTGRES_PORT = "POSTGRES_PORT"
|
|
134
|
+
KEY_POSTGRES_DATABASE_NAME = "POSTGRES_DATABASE_NAME"
|
|
135
|
+
KEY_POSTGRES_USERNAME = "POSTGRES_USERNAME"
|
|
136
|
+
KEY_POSTGRES_PASSWORD = "POSTGRES_PASSWORD"
|
|
137
|
+
# MSSQL
|
|
138
|
+
KEY_MSSQL_DIALECT = "MSSQL_DIALECT"
|
|
139
|
+
KEY_MSSQL_URL = "MSSQL_URL"
|
|
140
|
+
KEY_MSSQL_PORT = "MSSQL_PORT"
|
|
141
|
+
KEY_MSSQL_DATABASE_NAME = "MSSQL_DATABASE_NAME"
|
|
142
|
+
KEY_MSSQL_USERNAME = "MSSQL_USERNAME"
|
|
143
|
+
KEY_MSSQL_PASSWORD = "MSSQL_PASSWORD"
|
|
40
144
|
|
|
41
145
|
DEFAULT_MARKS = "smoke"
|
|
42
146
|
DEFAULT_XDIST_N = 8
|
|
@@ -46,11 +150,14 @@ AUTH_KEYS = [
|
|
|
46
150
|
KEY_AUTH_SERVER_URL,
|
|
47
151
|
KEY_AUTH_CLIENT_ID,
|
|
48
152
|
KEY_AUTH_CLIENT_SECRET,
|
|
153
|
+
KEY_AUTH_USERNAME,
|
|
154
|
+
KEY_AUTH_PASSWORD,
|
|
49
155
|
KEY_AUTH_REALM_NAME,
|
|
50
156
|
KEY_CODEMIE_API_DOMAIN,
|
|
51
157
|
]
|
|
52
158
|
|
|
53
|
-
|
|
159
|
+
# === CREDENTIAL CATEGORIES ===
|
|
160
|
+
VERSION_CONTROL_KEYS = [
|
|
54
161
|
KEY_GIT_ENV,
|
|
55
162
|
KEY_GITLAB_URL,
|
|
56
163
|
KEY_GITLAB_TOKEN,
|
|
@@ -59,10 +166,282 @@ INTEGRATION_KEYS = [
|
|
|
59
166
|
KEY_GITHUB_URL,
|
|
60
167
|
KEY_GITHUB_TOKEN,
|
|
61
168
|
KEY_GITHUB_PROJECT,
|
|
169
|
+
]
|
|
170
|
+
|
|
171
|
+
PROJECT_MANAGEMENT_KEYS = [
|
|
172
|
+
# JIRA Server
|
|
62
173
|
KEY_JIRA_URL,
|
|
63
174
|
KEY_JIRA_TOKEN,
|
|
64
175
|
KEY_JQL,
|
|
176
|
+
# JIRA Cloud
|
|
177
|
+
KEY_JIRA_CLOUD_URL,
|
|
178
|
+
KEY_JIRA_CLOUD_EMAIL,
|
|
179
|
+
KEY_JIRA_CLOUD_TOKEN,
|
|
180
|
+
KEY_JIRA_CLOUD_JQL,
|
|
181
|
+
# Confluence Server
|
|
65
182
|
KEY_CONFLUENCE_URL,
|
|
66
183
|
KEY_CONFLUENCE_TOKEN,
|
|
67
184
|
KEY_CQL,
|
|
185
|
+
# Confluence Cloud
|
|
186
|
+
KEY_CONFLUENCE_CLOUD_URL,
|
|
187
|
+
KEY_CONFLUENCE_CLOUD_EMAIL,
|
|
188
|
+
KEY_CONFLUENCE_CLOUD_TOKEN,
|
|
189
|
+
KEY_CONFLUENCE_CLOUD_CQL,
|
|
190
|
+
]
|
|
191
|
+
|
|
192
|
+
CLOUD_PROVIDERS_KEYS = [
|
|
193
|
+
# AWS
|
|
194
|
+
KEY_AWS_ACCESS_KEY_ID,
|
|
195
|
+
KEY_AWS_SECRET_ACCESS_KEY,
|
|
196
|
+
KEY_AWS_REGION,
|
|
197
|
+
KEY_AWS_SESSION_TOKEN,
|
|
198
|
+
# Azure
|
|
199
|
+
KEY_AZURE_CLIENT_ID,
|
|
200
|
+
KEY_AZURE_CLIENT_SECRET,
|
|
201
|
+
KEY_AZURE_TENANT_ID,
|
|
202
|
+
KEY_AZURE_SUBSCRIPTION_ID,
|
|
203
|
+
# GCP
|
|
204
|
+
KEY_GCP_SA_KEY_BASE64,
|
|
205
|
+
]
|
|
206
|
+
|
|
207
|
+
DEVELOPMENT_TOOLS_KEYS = [
|
|
208
|
+
# Azure DevOps
|
|
209
|
+
KEY_AZURE_DEVOPS_URL,
|
|
210
|
+
KEY_AZURE_DEVOPS_TOKEN,
|
|
211
|
+
KEY_AZURE_DEVOPS_PROJECT_NAME,
|
|
212
|
+
KEY_AZURE_DEVOPS_ORGANIZATION_NAME,
|
|
213
|
+
# ServiceNow
|
|
214
|
+
KEY_SERVICENOW_URL,
|
|
215
|
+
KEY_SERVICENOW_TOKEN,
|
|
216
|
+
# Keycloak
|
|
217
|
+
KEY_KEYCLOAK_URL,
|
|
218
|
+
KEY_KEYCLOAK_REALM,
|
|
219
|
+
KEY_KEYCLOAK_CLIENT_ID,
|
|
220
|
+
KEY_KEYCLOAK_CLIENT_SECRET,
|
|
221
|
+
# SonarQube Server
|
|
222
|
+
KEY_SONAR_URL,
|
|
223
|
+
KEY_SONAR_TOKEN,
|
|
224
|
+
KEY_SONAR_PROJECT_KEY,
|
|
225
|
+
# SonarCloud
|
|
226
|
+
KEY_SONAR_CLOUD_URL,
|
|
227
|
+
KEY_SONAR_CLOUD_TOKEN,
|
|
228
|
+
KEY_SONAR_CLOUD_PROJECT_KEY,
|
|
229
|
+
]
|
|
230
|
+
|
|
231
|
+
NOTIFICATIONS_KEYS = [
|
|
232
|
+
# Email/Gmail
|
|
233
|
+
KEY_GMAIL_URL,
|
|
234
|
+
KEY_SMTP_USERNAME,
|
|
235
|
+
KEY_SMTP_PASSWORD,
|
|
236
|
+
# OAuth
|
|
237
|
+
KEY_OAUTH_URL,
|
|
238
|
+
KEY_OAUTH_CLIENT_ID,
|
|
239
|
+
KEY_OAUTH_CLIENT_SECRET,
|
|
240
|
+
KEY_OAUTH_REFRESH_TOKEN,
|
|
241
|
+
# Telegram
|
|
242
|
+
KEY_TELEGRAM_TOKEN,
|
|
243
|
+
KEY_TELEGRAM_CHAT_ID,
|
|
244
|
+
]
|
|
245
|
+
|
|
246
|
+
RESEARCH_TOOLS_KEYS = [
|
|
247
|
+
# Kubernetes
|
|
248
|
+
KEY_KUBERNETES_URL,
|
|
249
|
+
KEY_KUBERNETES_TOKEN,
|
|
250
|
+
# Report Portal
|
|
251
|
+
KEY_REPORT_PORTAL_URL,
|
|
252
|
+
KEY_REPORT_PORTAL_API_KEY,
|
|
253
|
+
KEY_REPORT_PORTAL_PROJECT,
|
|
254
|
+
# Elasticsearch
|
|
255
|
+
KEY_ELASTICSEARCH_URL,
|
|
256
|
+
KEY_ELASTICSEARCH_API_KEY_ID,
|
|
257
|
+
KEY_ELASTICSEARCH_API_KEY,
|
|
68
258
|
]
|
|
259
|
+
|
|
260
|
+
DATA_MANAGEMENT_KEYS = [
|
|
261
|
+
# LiteLLM
|
|
262
|
+
KEY_LITE_LLM_API_KEY,
|
|
263
|
+
# MySQL
|
|
264
|
+
KEY_MYSQL_DIALECT,
|
|
265
|
+
KEY_MYSQL_URL,
|
|
266
|
+
KEY_MYSQL_PORT,
|
|
267
|
+
KEY_MYSQL_DATABASE_NAME,
|
|
268
|
+
KEY_MYSQL_USERNAME,
|
|
269
|
+
KEY_MYSQL_PASSWORD,
|
|
270
|
+
# PostgreSQL
|
|
271
|
+
KEY_POSTGRES_DIALECT,
|
|
272
|
+
KEY_POSTGRES_URL,
|
|
273
|
+
KEY_POSTGRES_PORT,
|
|
274
|
+
KEY_POSTGRES_DATABASE_NAME,
|
|
275
|
+
KEY_POSTGRES_USERNAME,
|
|
276
|
+
KEY_POSTGRES_PASSWORD,
|
|
277
|
+
# MSSQL
|
|
278
|
+
KEY_MSSQL_DIALECT,
|
|
279
|
+
KEY_MSSQL_URL,
|
|
280
|
+
KEY_MSSQL_PORT,
|
|
281
|
+
KEY_MSSQL_DATABASE_NAME,
|
|
282
|
+
KEY_MSSQL_USERNAME,
|
|
283
|
+
KEY_MSSQL_PASSWORD,
|
|
284
|
+
]
|
|
285
|
+
|
|
286
|
+
# Combined lists for backwards compatibility
|
|
287
|
+
INTEGRATION_KEYS = (
|
|
288
|
+
VERSION_CONTROL_KEYS
|
|
289
|
+
+ PROJECT_MANAGEMENT_KEYS
|
|
290
|
+
+ CLOUD_PROVIDERS_KEYS
|
|
291
|
+
+ DEVELOPMENT_TOOLS_KEYS
|
|
292
|
+
+ NOTIFICATIONS_KEYS
|
|
293
|
+
+ RESEARCH_TOOLS_KEYS
|
|
294
|
+
+ DATA_MANAGEMENT_KEYS
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
# Category mapping for CLI
|
|
298
|
+
CREDENTIAL_CATEGORIES = {
|
|
299
|
+
"version-control": {
|
|
300
|
+
"name": "Version Control Systems",
|
|
301
|
+
"description": "GitLab, GitHub, and other version control platforms",
|
|
302
|
+
"keys": VERSION_CONTROL_KEYS,
|
|
303
|
+
},
|
|
304
|
+
"code-base": {
|
|
305
|
+
"name": "Code Base",
|
|
306
|
+
"description": "SonarQube and code analysis tools",
|
|
307
|
+
"keys": [
|
|
308
|
+
KEY_SONAR_URL,
|
|
309
|
+
KEY_SONAR_TOKEN,
|
|
310
|
+
KEY_SONAR_PROJECT_KEY,
|
|
311
|
+
KEY_SONAR_CLOUD_URL,
|
|
312
|
+
KEY_SONAR_CLOUD_TOKEN,
|
|
313
|
+
KEY_SONAR_CLOUD_PROJECT_KEY,
|
|
314
|
+
],
|
|
315
|
+
},
|
|
316
|
+
"project-management": {
|
|
317
|
+
"name": "Project Management",
|
|
318
|
+
"description": "JIRA, Confluence, and project management tools",
|
|
319
|
+
"keys": PROJECT_MANAGEMENT_KEYS,
|
|
320
|
+
},
|
|
321
|
+
"cloud": {
|
|
322
|
+
"name": "Cloud",
|
|
323
|
+
"description": "AWS, GCP cloud services and Kubernetes configurations",
|
|
324
|
+
"keys": [
|
|
325
|
+
# AWS
|
|
326
|
+
KEY_AWS_ACCESS_KEY_ID,
|
|
327
|
+
KEY_AWS_SECRET_ACCESS_KEY,
|
|
328
|
+
KEY_AWS_REGION,
|
|
329
|
+
KEY_AWS_SESSION_TOKEN,
|
|
330
|
+
# GCP
|
|
331
|
+
KEY_GCP_SA_KEY_BASE64,
|
|
332
|
+
# Kubernetes
|
|
333
|
+
KEY_KUBERNETES_URL,
|
|
334
|
+
KEY_KUBERNETES_TOKEN,
|
|
335
|
+
# Azure Cloud
|
|
336
|
+
KEY_AZURE_CLIENT_ID,
|
|
337
|
+
KEY_AZURE_CLIENT_SECRET,
|
|
338
|
+
KEY_AZURE_TENANT_ID,
|
|
339
|
+
KEY_AZURE_SUBSCRIPTION_ID,
|
|
340
|
+
],
|
|
341
|
+
},
|
|
342
|
+
"azure-devops": {
|
|
343
|
+
"name": "Azure DevOps",
|
|
344
|
+
"description": "Azure DevOps and Azure cloud platform services",
|
|
345
|
+
"keys": [
|
|
346
|
+
# Azure DevOps
|
|
347
|
+
KEY_AZURE_DEVOPS_URL,
|
|
348
|
+
KEY_AZURE_DEVOPS_TOKEN,
|
|
349
|
+
KEY_AZURE_DEVOPS_PROJECT_NAME,
|
|
350
|
+
KEY_AZURE_DEVOPS_ORGANIZATION_NAME,
|
|
351
|
+
],
|
|
352
|
+
},
|
|
353
|
+
"access-management": {
|
|
354
|
+
"name": "Access Management",
|
|
355
|
+
"description": "Keycloak and identity management systems",
|
|
356
|
+
"keys": [
|
|
357
|
+
KEY_KEYCLOAK_URL,
|
|
358
|
+
KEY_KEYCLOAK_REALM,
|
|
359
|
+
KEY_KEYCLOAK_CLIENT_ID,
|
|
360
|
+
KEY_KEYCLOAK_CLIENT_SECRET,
|
|
361
|
+
],
|
|
362
|
+
},
|
|
363
|
+
"notification-systems": {
|
|
364
|
+
"name": "Notification Systems",
|
|
365
|
+
"description": "Email, OAuth, Telegram, and communication platforms",
|
|
366
|
+
"keys": NOTIFICATIONS_KEYS,
|
|
367
|
+
},
|
|
368
|
+
"data-management": {
|
|
369
|
+
"name": "Data Management",
|
|
370
|
+
"description": "SQL databases, Elasticsearch, and data storage systems",
|
|
371
|
+
"keys": DATA_MANAGEMENT_KEYS
|
|
372
|
+
+ [
|
|
373
|
+
KEY_ELASTICSEARCH_URL,
|
|
374
|
+
KEY_ELASTICSEARCH_API_KEY_ID,
|
|
375
|
+
KEY_ELASTICSEARCH_API_KEY,
|
|
376
|
+
],
|
|
377
|
+
},
|
|
378
|
+
"it-service-management": {
|
|
379
|
+
"name": "IT Service Management",
|
|
380
|
+
"description": "ServiceNow and IT service management platforms",
|
|
381
|
+
"keys": [
|
|
382
|
+
KEY_SERVICENOW_URL,
|
|
383
|
+
KEY_SERVICENOW_TOKEN,
|
|
384
|
+
],
|
|
385
|
+
},
|
|
386
|
+
"quality-assurance": {
|
|
387
|
+
"name": "Quality Assurance",
|
|
388
|
+
"description": "Report Portal and quality assurance tools",
|
|
389
|
+
"keys": [
|
|
390
|
+
KEY_REPORT_PORTAL_URL,
|
|
391
|
+
KEY_REPORT_PORTAL_API_KEY,
|
|
392
|
+
KEY_REPORT_PORTAL_PROJECT,
|
|
393
|
+
],
|
|
394
|
+
},
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
# Sensitive fields that should be masked in input/output
|
|
398
|
+
SENSITIVE_KEYS = {
|
|
399
|
+
KEY_AUTH_CLIENT_SECRET,
|
|
400
|
+
KEY_AUTH_PASSWORD,
|
|
401
|
+
KEY_GITLAB_TOKEN,
|
|
402
|
+
KEY_GITHUB_TOKEN,
|
|
403
|
+
KEY_JIRA_TOKEN,
|
|
404
|
+
KEY_JIRA_CLOUD_TOKEN,
|
|
405
|
+
KEY_CONFLUENCE_TOKEN,
|
|
406
|
+
KEY_CONFLUENCE_CLOUD_TOKEN,
|
|
407
|
+
KEY_AWS_SECRET_ACCESS_KEY,
|
|
408
|
+
KEY_AWS_SESSION_TOKEN,
|
|
409
|
+
KEY_AZURE_CLIENT_SECRET,
|
|
410
|
+
KEY_GCP_SA_KEY_BASE64,
|
|
411
|
+
KEY_AZURE_DEVOPS_TOKEN,
|
|
412
|
+
KEY_SERVICENOW_TOKEN,
|
|
413
|
+
KEY_KEYCLOAK_CLIENT_SECRET,
|
|
414
|
+
KEY_SONAR_TOKEN,
|
|
415
|
+
KEY_SONAR_CLOUD_TOKEN,
|
|
416
|
+
KEY_SMTP_PASSWORD,
|
|
417
|
+
KEY_OAUTH_CLIENT_SECRET,
|
|
418
|
+
KEY_OAUTH_REFRESH_TOKEN,
|
|
419
|
+
KEY_TELEGRAM_TOKEN,
|
|
420
|
+
KEY_KUBERNETES_TOKEN,
|
|
421
|
+
KEY_REPORT_PORTAL_API_KEY,
|
|
422
|
+
KEY_ELASTICSEARCH_API_KEY,
|
|
423
|
+
KEY_LITE_LLM_API_KEY,
|
|
424
|
+
KEY_MYSQL_PASSWORD,
|
|
425
|
+
KEY_POSTGRES_PASSWORD,
|
|
426
|
+
KEY_MSSQL_PASSWORD,
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def is_sensitive_key(key: str) -> bool:
|
|
431
|
+
"""Check if a credential key contains sensitive information."""
|
|
432
|
+
return key in SENSITIVE_KEYS
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
def mask_sensitive_value(value: str, show_real: bool = False) -> str:
|
|
436
|
+
"""Mask sensitive credential values for display.
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
value: The value to potentially mask
|
|
440
|
+
show_real: If True, return the real value instead of masking
|
|
441
|
+
"""
|
|
442
|
+
if show_real:
|
|
443
|
+
return value
|
|
444
|
+
|
|
445
|
+
if not value or len(value) < 4:
|
|
446
|
+
return "*" * len(value) if value else ""
|
|
447
|
+
return value[:2] + "*" * (len(value) - 4) + value[-2:]
|
|
@@ -43,3 +43,12 @@ def ensure_env_from_config(keys: list[str]) -> None:
|
|
|
43
43
|
for k in keys:
|
|
44
44
|
if k not in os.environ and k in cfg:
|
|
45
45
|
os.environ[k] = str(cfg[k])
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def unset_config_key(key: str) -> bool:
|
|
49
|
+
cfg = load_config()
|
|
50
|
+
if key in cfg:
|
|
51
|
+
del cfg[key]
|
|
52
|
+
save_config(cfg)
|
|
53
|
+
return True
|
|
54
|
+
return False
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test Data for Assistant UI Tests
|
|
3
|
+
|
|
4
|
+
This module provides test data generation and management for assistant-related UI tests.
|
|
5
|
+
Following best practices by separating test data from test logic and providing
|
|
6
|
+
reusable data factories for consistent testing.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from typing import Optional, List
|
|
11
|
+
|
|
12
|
+
from codemie_test_harness.tests.utils.base_utils import get_random_name
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class AssistantTestData:
|
|
17
|
+
"""
|
|
18
|
+
Data class for assistant test data.
|
|
19
|
+
|
|
20
|
+
This class encapsulates all the data needed for assistant creation tests,
|
|
21
|
+
providing a clean and type-safe way to manage test data.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
name: str
|
|
25
|
+
description: str
|
|
26
|
+
system_prompt: str
|
|
27
|
+
icon_url: Optional[str] = None
|
|
28
|
+
shared: bool = False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class AssistantTestDataFactory:
|
|
32
|
+
"""
|
|
33
|
+
Factory class for generating assistant test data.
|
|
34
|
+
|
|
35
|
+
This factory provides various methods to create different types of
|
|
36
|
+
assistant test data for different testing scenarios.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def create_minimal_assistant_data() -> AssistantTestData:
|
|
41
|
+
"""
|
|
42
|
+
Create minimal assistant data with only required fields.
|
|
43
|
+
|
|
44
|
+
This represents the most basic assistant creation scenario
|
|
45
|
+
with minimal required information.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
AssistantTestData: Minimal assistant test data
|
|
49
|
+
"""
|
|
50
|
+
return AssistantTestData(
|
|
51
|
+
name=f"QA Test Assistant {get_random_name()}",
|
|
52
|
+
description="Minimal test assistant for QA automation.",
|
|
53
|
+
system_prompt=(
|
|
54
|
+
"You are a test assistant created for QA validation purposes. "
|
|
55
|
+
"Provide helpful and accurate responses to user queries."
|
|
56
|
+
),
|
|
57
|
+
shared=False,
|
|
58
|
+
icon_url=ICON_URL,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def create_shared_assistant_data() -> AssistantTestData:
|
|
63
|
+
"""
|
|
64
|
+
Create shared assistant data for public/shared testing scenarios.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
AssistantTestData: Shared assistant test data
|
|
68
|
+
"""
|
|
69
|
+
return AssistantTestData(
|
|
70
|
+
name=f"QA Shared Assistant {get_random_name()}",
|
|
71
|
+
description="Shared QA assistant available to all team members",
|
|
72
|
+
system_prompt=(
|
|
73
|
+
"You are a shared QA assistant available to the entire team. "
|
|
74
|
+
"Provide collaborative testing support, knowledge sharing, and "
|
|
75
|
+
"help maintain consistent quality standards across projects."
|
|
76
|
+
),
|
|
77
|
+
icon_url=ICON_URL,
|
|
78
|
+
shared=True,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
def create_validation_test_data() -> List[AssistantTestData]:
|
|
83
|
+
"""
|
|
84
|
+
Create a list of assistant data for validation testing scenarios.
|
|
85
|
+
|
|
86
|
+
This includes data for testing various validation scenarios,
|
|
87
|
+
edge cases in form validation, and error handling.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
List[AssistantTestData]: List of validation test data
|
|
91
|
+
"""
|
|
92
|
+
return [
|
|
93
|
+
# Empty name scenario
|
|
94
|
+
AssistantTestData(
|
|
95
|
+
name="",
|
|
96
|
+
description="Test description",
|
|
97
|
+
system_prompt="Test prompt",
|
|
98
|
+
),
|
|
99
|
+
# Long name scenario
|
|
100
|
+
AssistantTestData(
|
|
101
|
+
name="A" * 100, # Very long name
|
|
102
|
+
description="Test description for long name validation",
|
|
103
|
+
system_prompt="Test prompt for long name scenario",
|
|
104
|
+
),
|
|
105
|
+
# Empty description scenario
|
|
106
|
+
AssistantTestData(
|
|
107
|
+
name="Test Assistant",
|
|
108
|
+
description="",
|
|
109
|
+
system_prompt="Test prompt",
|
|
110
|
+
),
|
|
111
|
+
# Empty system prompt scenario
|
|
112
|
+
AssistantTestData(
|
|
113
|
+
name="Test Assistant",
|
|
114
|
+
description="Test description",
|
|
115
|
+
system_prompt="",
|
|
116
|
+
),
|
|
117
|
+
]
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class AssistantValidationRules:
|
|
121
|
+
"""
|
|
122
|
+
Validation rules and constraints for assistant data.
|
|
123
|
+
|
|
124
|
+
This class defines the validation rules that should be applied
|
|
125
|
+
to assistant data during testing.
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
# Field length constraints
|
|
129
|
+
MAX_NAME_LENGTH = 100
|
|
130
|
+
MAX_DESCRIPTION_LENGTH = 1000
|
|
131
|
+
MAX_ICON_URL_LENGTH = 500
|
|
132
|
+
|
|
133
|
+
# Required fields
|
|
134
|
+
REQUIRED_FIELDS = ["name", "description", "system_prompt"]
|
|
135
|
+
|
|
136
|
+
# Validation error messages (expected messages for testing)
|
|
137
|
+
ERROR_MESSAGES = {
|
|
138
|
+
"name_required": "Name is required",
|
|
139
|
+
"name_too_long": f"Name must be less than {MAX_NAME_LENGTH} characters",
|
|
140
|
+
"description_required": "Description is required",
|
|
141
|
+
"description_too_long": f"Description must be less than {MAX_DESCRIPTION_LENGTH} characters",
|
|
142
|
+
"system_prompt_required": "System prompt is required",
|
|
143
|
+
"invalid_url": "Please enter a valid URL",
|
|
144
|
+
"invalid_type": "Please select a valid assistant type",
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
# ==================== CONVENIENCE FUNCTIONS ====================
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def get_minimal_assistant_data() -> AssistantTestData:
|
|
152
|
+
"""Convenience function to get minimal assistant data."""
|
|
153
|
+
return AssistantTestDataFactory.create_minimal_assistant_data()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def get_shared_assistant_data() -> AssistantTestData:
|
|
157
|
+
"""Convenience function to get shared assistant data."""
|
|
158
|
+
return AssistantTestDataFactory.create_shared_assistant_data()
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def get_validation_test_data() -> List[AssistantTestData]:
|
|
162
|
+
"""Convenience function to get validation test data."""
|
|
163
|
+
return AssistantTestDataFactory.create_validation_test_data()
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
# ==================== TEST DATA CONSTANTS ====================
|
|
167
|
+
|
|
168
|
+
# Common test values for reuse
|
|
169
|
+
COMMON_TEST_PROMPTS = {
|
|
170
|
+
"qa_assistant": (
|
|
171
|
+
"You are a QA testing assistant. Your primary role is to help with "
|
|
172
|
+
"quality assurance tasks, test automation, and ensuring software quality. "
|
|
173
|
+
"Provide detailed and actionable guidance."
|
|
174
|
+
),
|
|
175
|
+
"general_assistant": (
|
|
176
|
+
"You are a helpful assistant. Provide clear, accurate, and helpful "
|
|
177
|
+
"responses to user queries. Always be polite and professional."
|
|
178
|
+
),
|
|
179
|
+
"specialist_assistant": (
|
|
180
|
+
"You are a specialist assistant with deep expertise in your domain. "
|
|
181
|
+
"Provide expert-level guidance and detailed technical solutions."
|
|
182
|
+
),
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
COMMON_TEST_DESCRIPTIONS = {
|
|
186
|
+
"qa_assistant": "QA testing assistant for automation and quality assurance tasks",
|
|
187
|
+
"general_assistant": "General purpose assistant for various tasks and queries",
|
|
188
|
+
"specialist_assistant": "Specialist assistant with domain-specific expertise",
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
COMMON_ICON_URLS = {
|
|
192
|
+
"qa_icon": "https://example.com/qa-assistant-icon.png",
|
|
193
|
+
"general_icon": "https://example.com/general-assistant-icon.png",
|
|
194
|
+
"specialist_icon": "https://example.com/specialist-assistant-icon.png",
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
ICON_URL = "https://raw.githubusercontent.com/epam-gen-ai-run/ai-run-install/main/docs/assets/ai/AQAUiTestGenerator.png"
|