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.

Files changed (22) hide show
  1. codemie_test_harness/cli/cli.py +18 -74
  2. codemie_test_harness/cli/commands/assistant_cmd.py +104 -0
  3. codemie_test_harness/cli/commands/config_cmd.py +610 -20
  4. codemie_test_harness/cli/commands/workflow_cmd.py +64 -0
  5. codemie_test_harness/cli/constants.py +385 -6
  6. codemie_test_harness/cli/utils.py +9 -0
  7. codemie_test_harness/tests/test_data/assistant_test_data.py +197 -0
  8. codemie_test_harness/tests/test_data/project_management_test_data.py +1 -1
  9. codemie_test_harness/tests/ui/assistants/__init__.py +0 -0
  10. codemie_test_harness/tests/ui/assistants/test_create_assistant.py +408 -0
  11. codemie_test_harness/tests/ui/conftest.py +23 -3
  12. codemie_test_harness/tests/ui/pageobject/assistants/assistants_page.py +3 -4
  13. codemie_test_harness/tests/ui/pageobject/assistants/create_assistant_page.py +689 -0
  14. codemie_test_harness/tests/ui/pageobject/assistants/generate_with_ai_modal.py +367 -0
  15. codemie_test_harness/tests/ui/pageobject/base_page.py +2 -2
  16. codemie_test_harness/tests/ui/pytest.ini +18 -0
  17. codemie_test_harness/tests/ui/workflows/test_workflows.py +1 -1
  18. codemie_test_harness/tests/utils/credentials_manager.py +0 -15
  19. {codemie_test_harness-0.1.168.dist-info → codemie_test_harness-0.1.170.dist-info}/METADATA +2 -2
  20. {codemie_test_harness-0.1.168.dist-info → codemie_test_harness-0.1.170.dist-info}/RECORD +22 -14
  21. {codemie_test_harness-0.1.168.dist-info → codemie_test_harness-0.1.170.dist-info}/WHEEL +0 -0
  22. {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
- # Integrations / external systems
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
- # JIRA
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 = "JQL"
36
- # Confluence
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 = "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
- INTEGRATION_KEYS = [
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"