codemie-test-harness 0.1.172__py3-none-any.whl → 0.1.174__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.
- codemie_test_harness/tests/ui/_test_data/__init__.py +0 -0
- codemie_test_harness/tests/ui/_test_data/integration_test_data.py +121 -0
- codemie_test_harness/tests/ui/assistants/test_create_assistant.py +1 -1
- codemie_test_harness/tests/ui/conftest.py +25 -0
- codemie_test_harness/tests/ui/integrations/__init__.py +0 -0
- codemie_test_harness/tests/ui/integrations/test_create_integration.py +320 -0
- codemie_test_harness/tests/ui/pageobject/assistants/create_assistant_page.py +0 -20
- codemie_test_harness/tests/ui/pageobject/base_page.py +19 -6
- codemie_test_harness/tests/ui/pageobject/components/integration_row.py +299 -0
- codemie_test_harness/tests/ui/pageobject/integrations/create_integration_page.py +772 -0
- codemie_test_harness/tests/ui/pageobject/integrations/integrations_page.py +434 -0
- codemie_test_harness-0.1.174.dist-info/METADATA +567 -0
- {codemie_test_harness-0.1.172.dist-info → codemie_test_harness-0.1.174.dist-info}/RECORD +16 -9
- codemie_test_harness-0.1.172.dist-info/METADATA +0 -306
- /codemie_test_harness/tests/{test_data → ui/_test_data}/assistant_test_data.py +0 -0
- {codemie_test_harness-0.1.172.dist-info → codemie_test_harness-0.1.174.dist-info}/WHEEL +0 -0
- {codemie_test_harness-0.1.172.dist-info → codemie_test_harness-0.1.174.dist-info}/entry_points.txt +0 -0
|
File without changes
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Helper utilities for integration UI tests.
|
|
3
|
+
Contains reusable functions and data generators for integration testing.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Dict, Any
|
|
8
|
+
|
|
9
|
+
from codemie_sdk.models.integration import CredentialTypes
|
|
10
|
+
|
|
11
|
+
from codemie_test_harness.tests import PROJECT
|
|
12
|
+
from codemie_test_harness.tests.utils.base_utils import get_random_name
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class IntegrationTestData:
|
|
17
|
+
"""Data class for integration form fields."""
|
|
18
|
+
|
|
19
|
+
project: str
|
|
20
|
+
alias: str
|
|
21
|
+
description: str
|
|
22
|
+
credential_type: CredentialTypes
|
|
23
|
+
is_global: bool = False
|
|
24
|
+
fields: Dict[str, Any] = None
|
|
25
|
+
|
|
26
|
+
def __post_init__(self):
|
|
27
|
+
if self.fields is None:
|
|
28
|
+
self.fields = {}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class IntegrationTestDataFactory:
|
|
32
|
+
@staticmethod
|
|
33
|
+
def jira_integration() -> IntegrationTestData:
|
|
34
|
+
return IntegrationTestData(
|
|
35
|
+
project=PROJECT,
|
|
36
|
+
alias=f"JIRA Server Integration {get_random_name()}",
|
|
37
|
+
description="JIRA Server integration for project management",
|
|
38
|
+
credential_type=CredentialTypes.JIRA,
|
|
39
|
+
fields={
|
|
40
|
+
"url": "https://jira.company.com",
|
|
41
|
+
"username": "test.user@company.com",
|
|
42
|
+
"token": "secure_password",
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def jira_cloud_integration() -> IntegrationTestData:
|
|
48
|
+
return IntegrationTestData(
|
|
49
|
+
project=PROJECT,
|
|
50
|
+
alias=f"JIRA Cloud Integration {get_random_name()}",
|
|
51
|
+
description="JIRA Cloud integration with API token",
|
|
52
|
+
credential_type=CredentialTypes.JIRA,
|
|
53
|
+
fields={
|
|
54
|
+
"url": "https://jiraeu.epam.com",
|
|
55
|
+
"username": "test.user@company.com",
|
|
56
|
+
"token": "ATATT3xFfGF0...",
|
|
57
|
+
"is_cloud": True,
|
|
58
|
+
},
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def git_integration() -> IntegrationTestData:
|
|
63
|
+
return IntegrationTestData(
|
|
64
|
+
project=PROJECT,
|
|
65
|
+
alias=f"GitLab Integration {get_random_name()}",
|
|
66
|
+
description="GitLab integration for code repository access",
|
|
67
|
+
credential_type=CredentialTypes.GIT,
|
|
68
|
+
fields={
|
|
69
|
+
"url": "https://gitlab.company.com",
|
|
70
|
+
"token": "glpat-1234567890abcdef",
|
|
71
|
+
},
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
@staticmethod
|
|
75
|
+
def confluence_integration() -> IntegrationTestData:
|
|
76
|
+
return IntegrationTestData(
|
|
77
|
+
project=PROJECT,
|
|
78
|
+
alias=f"Confluence Integration {get_random_name()}",
|
|
79
|
+
description="Confluence integration for project management",
|
|
80
|
+
credential_type=CredentialTypes.CONFLUENCE,
|
|
81
|
+
fields={
|
|
82
|
+
"url": "https://kb.epam.com",
|
|
83
|
+
"username": "test.user@company.com",
|
|
84
|
+
"token": "secure_password",
|
|
85
|
+
"is_cloud": False,
|
|
86
|
+
},
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
@staticmethod
|
|
90
|
+
def confluence_cloud_integration() -> IntegrationTestData:
|
|
91
|
+
return IntegrationTestData(
|
|
92
|
+
project=PROJECT,
|
|
93
|
+
alias=f"Confluence Cloud Integration {get_random_name()}",
|
|
94
|
+
description="Confluence Cloud integration for project management",
|
|
95
|
+
credential_type=CredentialTypes.CONFLUENCE,
|
|
96
|
+
fields={
|
|
97
|
+
"url": "https://company.atlassian.net",
|
|
98
|
+
"username": "test.user@company.com",
|
|
99
|
+
"token": "ATATT3xFfGF0...",
|
|
100
|
+
"is_cloud": True,
|
|
101
|
+
},
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# Expected validation messages
|
|
105
|
+
validation_messages = {
|
|
106
|
+
"invalid_email": "Please enter a valid email address",
|
|
107
|
+
"invalid_url": "Please enter a valid URL",
|
|
108
|
+
"duplicate_name": "An integration with this name already exists",
|
|
109
|
+
"connection_failed": "Connection test failed",
|
|
110
|
+
"connection_timeout": "Connection timeout",
|
|
111
|
+
"cannot_create_setting": "Cannot create specified setting",
|
|
112
|
+
"alias_required": "Alias is required",
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# Success messages
|
|
116
|
+
success_messages = {
|
|
117
|
+
"integration_created": "Integration created successfully",
|
|
118
|
+
"integration_updated": "Integration updated successfully",
|
|
119
|
+
"connection_test_passed": "Connection test passed",
|
|
120
|
+
"integration_deleted": "Integration deleted successfully",
|
|
121
|
+
}
|
|
@@ -26,7 +26,7 @@ Architecture:
|
|
|
26
26
|
|
|
27
27
|
import pytest
|
|
28
28
|
|
|
29
|
-
from codemie_test_harness.tests.
|
|
29
|
+
from codemie_test_harness.tests.ui._test_data.assistant_test_data import (
|
|
30
30
|
get_minimal_assistant_data,
|
|
31
31
|
)
|
|
32
32
|
from codemie_test_harness.tests.ui.pageobject.assistants.assistants_page import (
|
|
@@ -4,6 +4,7 @@ from datetime import datetime
|
|
|
4
4
|
from time import sleep
|
|
5
5
|
|
|
6
6
|
import pytest
|
|
7
|
+
from codemie_sdk.models.integration import IntegrationType
|
|
7
8
|
from reportportal_client import RPLogger, RPLogHandler
|
|
8
9
|
|
|
9
10
|
from codemie_test_harness.tests import autotest_entity_prefix
|
|
@@ -96,6 +97,7 @@ def pytest_sessionfinish(session):
|
|
|
96
97
|
clean_up_timeout = 1 if EnvironmentResolver.is_production() else 0
|
|
97
98
|
client = get_client()
|
|
98
99
|
prefix = autotest_entity_prefix
|
|
100
|
+
# Assistants
|
|
99
101
|
assistants = client.assistants.list(filters={"search": prefix}, per_page=200)
|
|
100
102
|
for assistant in assistants:
|
|
101
103
|
if prefix in assistant.name:
|
|
@@ -105,3 +107,26 @@ def pytest_sessionfinish(session):
|
|
|
105
107
|
for conversation in conversations:
|
|
106
108
|
client.conversations.delete(conversation.id)
|
|
107
109
|
sleep(clean_up_timeout)
|
|
110
|
+
# Integrations
|
|
111
|
+
integrations = client.integrations.list(
|
|
112
|
+
setting_type=IntegrationType.PROJECT,
|
|
113
|
+
filters={"search": autotest_entity_prefix},
|
|
114
|
+
per_page=200,
|
|
115
|
+
)
|
|
116
|
+
for integration in integrations:
|
|
117
|
+
if prefix in integration.alias:
|
|
118
|
+
client.integrations.delete(
|
|
119
|
+
setting_id=integration.id, setting_type=IntegrationType.PROJECT
|
|
120
|
+
)
|
|
121
|
+
sleep(clean_up_timeout)
|
|
122
|
+
integrations = client.integrations.list(
|
|
123
|
+
setting_type=IntegrationType.USER,
|
|
124
|
+
filters={"search": autotest_entity_prefix},
|
|
125
|
+
per_page=200,
|
|
126
|
+
)
|
|
127
|
+
for integration in integrations:
|
|
128
|
+
if prefix in integration.alias:
|
|
129
|
+
client.integrations.delete(
|
|
130
|
+
setting_id=integration.id, setting_type=IntegrationType.USER
|
|
131
|
+
)
|
|
132
|
+
sleep(clean_up_timeout)
|
|
File without changes
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
"""
|
|
2
|
+
UI tests for Create Integration feature - critical paths with best practices.
|
|
3
|
+
|
|
4
|
+
This test suite covers the essential "Create Integration" workflow focusing on happy path scenarios.
|
|
5
|
+
All tests follow the Page Object Model pattern with reusable components abstracted in standalone classes.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
from codemie_sdk.models.integration import CredentialTypes
|
|
10
|
+
|
|
11
|
+
from codemie_test_harness.tests.ui._test_data.integration_test_data import (
|
|
12
|
+
IntegrationTestDataFactory,
|
|
13
|
+
)
|
|
14
|
+
from codemie_test_harness.tests.ui.pageobject.integrations.create_integration_page import (
|
|
15
|
+
CreateIntegrationPage,
|
|
16
|
+
)
|
|
17
|
+
from codemie_test_harness.tests.ui.pageobject.integrations.integrations_page import (
|
|
18
|
+
IntegrationsPage,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# noinspection PyArgumentList
|
|
23
|
+
class TestCreateIntegrationNavigation:
|
|
24
|
+
"""Test class for integration creation navigation and page access."""
|
|
25
|
+
|
|
26
|
+
@pytest.mark.integration_ui
|
|
27
|
+
@pytest.mark.ui
|
|
28
|
+
@pytest.mark.smoke
|
|
29
|
+
def test_navigate_to_integrations_via_menu(self, page):
|
|
30
|
+
"""
|
|
31
|
+
Test navigation to create integration page via menu.
|
|
32
|
+
|
|
33
|
+
Verifies:
|
|
34
|
+
- User can navigate to integrations page from menu
|
|
35
|
+
- Main UI elements are visible on Integrations page
|
|
36
|
+
"""
|
|
37
|
+
# Arrange
|
|
38
|
+
integrations_page = IntegrationsPage(page)
|
|
39
|
+
|
|
40
|
+
# Act
|
|
41
|
+
integrations_page.navigate_to_via_menu()
|
|
42
|
+
|
|
43
|
+
# Assert
|
|
44
|
+
integrations_page.should_be_on_integrations_page()
|
|
45
|
+
integrations_page.should_see_create_integration_button()
|
|
46
|
+
integrations_page.should_see_integration_type_switcher()
|
|
47
|
+
integrations_page.should_see_integrations_table()
|
|
48
|
+
|
|
49
|
+
@pytest.mark.integration_ui
|
|
50
|
+
@pytest.mark.ui
|
|
51
|
+
@pytest.mark.smoke
|
|
52
|
+
def test_navigate_to_create_integration_via_direct_url(self, page):
|
|
53
|
+
"""
|
|
54
|
+
Test direct navigation to create integration page via URL.
|
|
55
|
+
|
|
56
|
+
Verifies:
|
|
57
|
+
- Direct URL access works correctly
|
|
58
|
+
- Page Title matches integration type
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
create_integration_page = CreateIntegrationPage(page)
|
|
62
|
+
|
|
63
|
+
# Act
|
|
64
|
+
create_integration_page.navigate_to_user_integration_creation()
|
|
65
|
+
|
|
66
|
+
# Assert
|
|
67
|
+
create_integration_page.should_be_on_create_user_integration_page()
|
|
68
|
+
|
|
69
|
+
# Act
|
|
70
|
+
create_integration_page.navigate_to_project_integration_creation()
|
|
71
|
+
|
|
72
|
+
# Assert
|
|
73
|
+
create_integration_page.should_be_on_create_project_integration_page()
|
|
74
|
+
|
|
75
|
+
@pytest.mark.integration_ui
|
|
76
|
+
@pytest.mark.ui
|
|
77
|
+
@pytest.mark.smoke
|
|
78
|
+
def test_navigate_to_create_integration_from_integrations_page(self, page):
|
|
79
|
+
"""
|
|
80
|
+
Test navigation to create integration page from integrations page ui elements.
|
|
81
|
+
|
|
82
|
+
Verifies:
|
|
83
|
+
- Navigation via UI elements works correctly
|
|
84
|
+
- Page Title matches integration type
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
integrations_page = IntegrationsPage(page)
|
|
88
|
+
|
|
89
|
+
# Navigate to User Integration creation
|
|
90
|
+
integrations_page.navigate_to().navigate_to_user_integration_creation()
|
|
91
|
+
|
|
92
|
+
create_integration_page = CreateIntegrationPage(page)
|
|
93
|
+
|
|
94
|
+
# Assert
|
|
95
|
+
create_integration_page.should_be_on_create_user_integration_page()
|
|
96
|
+
|
|
97
|
+
# Navigate to Project Integration creation
|
|
98
|
+
integrations_page.navigate_to().navigate_to_project_integration_creation()
|
|
99
|
+
|
|
100
|
+
# Assert
|
|
101
|
+
create_integration_page.should_be_on_create_project_integration_page()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# noinspection PyArgumentList
|
|
105
|
+
class TestIntegrationCreationPageElements:
|
|
106
|
+
"""Test class for integration creation page elements display."""
|
|
107
|
+
|
|
108
|
+
@pytest.mark.integration_ui
|
|
109
|
+
@pytest.mark.ui
|
|
110
|
+
@pytest.mark.smoke
|
|
111
|
+
@pytest.mark.parametrize(
|
|
112
|
+
"credential_type",
|
|
113
|
+
[CredentialTypes.GIT, CredentialTypes.JIRA, CredentialTypes.CONFLUENCE],
|
|
114
|
+
)
|
|
115
|
+
def test_create_integration_type_form_fields(self, page, credential_type):
|
|
116
|
+
"""
|
|
117
|
+
Test that all required form fields are displayed for Git credential type.
|
|
118
|
+
|
|
119
|
+
Verifies:
|
|
120
|
+
- Page navigation and structure validation
|
|
121
|
+
- Action buttons visibility (Back, Cancel, Create)
|
|
122
|
+
- Project selector element presence
|
|
123
|
+
- Global Integration toggle visibility
|
|
124
|
+
- Credential Type field with "Git" value
|
|
125
|
+
- Alias field with required indicator
|
|
126
|
+
- Authentication section with all fields (URL, Token name, Token)
|
|
127
|
+
- Help text and information tooltips
|
|
128
|
+
- Form field interactivity validation
|
|
129
|
+
- Create button initial disabled state
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
create_integration_page = CreateIntegrationPage(page)
|
|
133
|
+
|
|
134
|
+
# Act
|
|
135
|
+
create_integration_page.navigate_to_user_integration_creation()
|
|
136
|
+
create_integration_page.select_credential_type(credential_type)
|
|
137
|
+
|
|
138
|
+
# Assert - Verify page structure (includes title validation)
|
|
139
|
+
create_integration_page.should_be_on_create_user_integration_page()
|
|
140
|
+
|
|
141
|
+
# Assert - Verify UI elements visibility
|
|
142
|
+
(
|
|
143
|
+
create_integration_page.should_have_action_buttons_visible(credential_type)
|
|
144
|
+
.should_have_project_selector_visible()
|
|
145
|
+
.should_have_global_integration_toggle_visible()
|
|
146
|
+
.should_have_credential_type_field_visible()
|
|
147
|
+
.should_have_alias_field_visible()
|
|
148
|
+
.should_have_authentication_section_visible(credential_type)
|
|
149
|
+
.should_have_help_texts_visible()
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
# Assert - Verify credential type value
|
|
153
|
+
create_integration_page.should_have_credential_type_selected(credential_type)
|
|
154
|
+
|
|
155
|
+
# Assert - Verify form elements are interactive
|
|
156
|
+
create_integration_page.should_have_input_fields_editable()
|
|
157
|
+
|
|
158
|
+
# Assert - Verify Create button initial state
|
|
159
|
+
create_integration_page.should_have_create_button_enabled()
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
# noinspection PyArgumentList
|
|
163
|
+
class TestIntegrationCreationWorkflow:
|
|
164
|
+
"""Test class for the complete integration creation workflow."""
|
|
165
|
+
|
|
166
|
+
@pytest.mark.integration_ui
|
|
167
|
+
@pytest.mark.ui
|
|
168
|
+
@pytest.mark.smoke
|
|
169
|
+
def test_create_git_integration_complete_workflow(self, page):
|
|
170
|
+
"""
|
|
171
|
+
Test the complete Git integration creation workflow (happy path).
|
|
172
|
+
|
|
173
|
+
Verifies the end-to-end workflow for Git integration creation.
|
|
174
|
+
"""
|
|
175
|
+
# Arrange
|
|
176
|
+
integrations_page = IntegrationsPage(page)
|
|
177
|
+
create_integration_page = CreateIntegrationPage(page)
|
|
178
|
+
integration_test_data = IntegrationTestDataFactory.git_integration()
|
|
179
|
+
|
|
180
|
+
# Act - Navigate and create
|
|
181
|
+
create_integration_page.navigate_to_user_integration_creation()
|
|
182
|
+
create_integration_page.fill_git_integration_form(integration_test_data)
|
|
183
|
+
create_integration_page.create_integration()
|
|
184
|
+
|
|
185
|
+
# Assert
|
|
186
|
+
(
|
|
187
|
+
integrations_page.navigate_to()
|
|
188
|
+
.should_see_message(
|
|
189
|
+
IntegrationTestDataFactory.success_messages["integration_created"]
|
|
190
|
+
)
|
|
191
|
+
.should_see_specific_integration(integration_test_data.alias)
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
@pytest.mark.integration_ui
|
|
195
|
+
@pytest.mark.ui
|
|
196
|
+
@pytest.mark.smoke
|
|
197
|
+
def test_create_jira_integration_complete_workflow(self, page):
|
|
198
|
+
"""
|
|
199
|
+
Test the complete Jira integration creation workflow (happy path).
|
|
200
|
+
|
|
201
|
+
Verifies the end-to-end workflow for Jira integration creation including:
|
|
202
|
+
- Navigation to user integration creation page
|
|
203
|
+
- Credential type selection (Jira)
|
|
204
|
+
- Form filling with valid Jira integration data
|
|
205
|
+
- Integration creation and success validation
|
|
206
|
+
- Verification of created integration in integrations list
|
|
207
|
+
"""
|
|
208
|
+
# Arrange
|
|
209
|
+
integrations_page = IntegrationsPage(page)
|
|
210
|
+
create_integration_page = CreateIntegrationPage(page)
|
|
211
|
+
integration_test_data = IntegrationTestDataFactory.jira_integration()
|
|
212
|
+
|
|
213
|
+
# Act - Navigate and create
|
|
214
|
+
create_integration_page.navigate_to_user_integration_creation()
|
|
215
|
+
create_integration_page.fill_jira_integration_form(integration_test_data)
|
|
216
|
+
create_integration_page.create_integration()
|
|
217
|
+
|
|
218
|
+
# Assert
|
|
219
|
+
(
|
|
220
|
+
integrations_page.navigate_to()
|
|
221
|
+
.should_see_message(
|
|
222
|
+
IntegrationTestDataFactory.success_messages["integration_created"]
|
|
223
|
+
)
|
|
224
|
+
.should_see_specific_integration(integration_test_data.alias)
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
@pytest.mark.integration_ui
|
|
228
|
+
@pytest.mark.ui
|
|
229
|
+
@pytest.mark.smoke
|
|
230
|
+
def test_create_confluence_integration_complete_workflow(self, page):
|
|
231
|
+
"""
|
|
232
|
+
Test the complete Confluence integration creation workflow (happy path).
|
|
233
|
+
|
|
234
|
+
Verifies the end-to-end workflow for Confluence integration creation including:
|
|
235
|
+
- Navigation to user integration creation page
|
|
236
|
+
- Credential type selection (Confluence)
|
|
237
|
+
- Form filling with valid Confluence integration data
|
|
238
|
+
- Integration creation and success validation
|
|
239
|
+
- Verification of created integration in integrations list
|
|
240
|
+
"""
|
|
241
|
+
# Arrange
|
|
242
|
+
integrations_page = IntegrationsPage(page)
|
|
243
|
+
create_integration_page = CreateIntegrationPage(page)
|
|
244
|
+
integration_test_data = IntegrationTestDataFactory.confluence_integration()
|
|
245
|
+
|
|
246
|
+
# Act - Navigate and create
|
|
247
|
+
create_integration_page.navigate_to_user_integration_creation()
|
|
248
|
+
create_integration_page.fill_confluence_integration_form(integration_test_data)
|
|
249
|
+
create_integration_page.create_integration()
|
|
250
|
+
|
|
251
|
+
# Assert
|
|
252
|
+
(
|
|
253
|
+
integrations_page.navigate_to()
|
|
254
|
+
.should_see_message(
|
|
255
|
+
IntegrationTestDataFactory.success_messages["integration_created"]
|
|
256
|
+
)
|
|
257
|
+
.should_see_specific_integration(integration_test_data.alias)
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
# noinspection PyArgumentList
|
|
262
|
+
class TestIntegrationFormUserExperience:
|
|
263
|
+
"""Test class for integration form user experience and usability."""
|
|
264
|
+
|
|
265
|
+
@pytest.mark.integration_ui
|
|
266
|
+
@pytest.mark.ui
|
|
267
|
+
@pytest.mark.smoke
|
|
268
|
+
def test_form_reset_and_cancel_functionality(self, page):
|
|
269
|
+
"""
|
|
270
|
+
Test form reset and cancel functionality.
|
|
271
|
+
|
|
272
|
+
Verifies:
|
|
273
|
+
- Cancel button navigates away from form
|
|
274
|
+
- Form data is not saved when cancelled
|
|
275
|
+
- User can safely exit creation process
|
|
276
|
+
"""
|
|
277
|
+
# Arrange
|
|
278
|
+
create_integration_page = CreateIntegrationPage(page)
|
|
279
|
+
integrations_page = IntegrationsPage(page)
|
|
280
|
+
|
|
281
|
+
# Act
|
|
282
|
+
cancelled_integration_alias = "Test Integration to Cancel"
|
|
283
|
+
create_integration_page.navigate_to_user_integration_creation()
|
|
284
|
+
create_integration_page.fill_alias(cancelled_integration_alias)
|
|
285
|
+
create_integration_page.cancel_creation()
|
|
286
|
+
|
|
287
|
+
# Assert - Should navigate back to integrations page
|
|
288
|
+
integrations_page.should_have_page_title("Integrations")
|
|
289
|
+
|
|
290
|
+
# Verify the cancelled integration was not created
|
|
291
|
+
integrations_page.should_not_see_integration(cancelled_integration_alias)
|
|
292
|
+
|
|
293
|
+
@pytest.mark.integration_ui
|
|
294
|
+
@pytest.mark.ui
|
|
295
|
+
@pytest.mark.smoke
|
|
296
|
+
def test_alias_field_validation_message(self, page):
|
|
297
|
+
"""
|
|
298
|
+
Test validation message when alias field is empty and form is submitted.
|
|
299
|
+
|
|
300
|
+
Verifies:
|
|
301
|
+
- Error toast notification appears with correct header
|
|
302
|
+
- Error message contains "Alias is required" text
|
|
303
|
+
- Toast notification is visible and readable
|
|
304
|
+
"""
|
|
305
|
+
# Arrange
|
|
306
|
+
create_integration_page = CreateIntegrationPage(page)
|
|
307
|
+
|
|
308
|
+
# Act - Navigate to integration creation and try to submit without alias
|
|
309
|
+
create_integration_page.navigate_to_user_integration_creation()
|
|
310
|
+
create_integration_page.select_credential_type(CredentialTypes.GIT)
|
|
311
|
+
# Leave alias field empty intentionally
|
|
312
|
+
create_integration_page.create_integration()
|
|
313
|
+
|
|
314
|
+
# Assert - Verify error toast notification appears
|
|
315
|
+
create_integration_page.should_see_error_toast_message(
|
|
316
|
+
header=IntegrationTestDataFactory.validation_messages[
|
|
317
|
+
"cannot_create_setting"
|
|
318
|
+
],
|
|
319
|
+
content=IntegrationTestDataFactory.validation_messages["alias_required"],
|
|
320
|
+
)
|
|
@@ -47,17 +47,6 @@ class CreateAssistantPage(BasePage):
|
|
|
47
47
|
or self.page.locator('h1:has-text("Create Assistant")')
|
|
48
48
|
)
|
|
49
49
|
|
|
50
|
-
@property
|
|
51
|
-
def back_button(self) -> Locator:
|
|
52
|
-
"""Back button in header with arrow icon"""
|
|
53
|
-
return (
|
|
54
|
-
self.page.locator("button.button.secondary.medium").first
|
|
55
|
-
or self.page.locator(
|
|
56
|
-
'button:has(svg[xmlns="http://www.w3.org/2000/svg"])'
|
|
57
|
-
).first
|
|
58
|
-
or self.page.locator(".mr-6 button")
|
|
59
|
-
)
|
|
60
|
-
|
|
61
50
|
@property
|
|
62
51
|
def generate_with_ai_button(self) -> Locator:
|
|
63
52
|
"""Generate with AI button in header with magical styling"""
|
|
@@ -71,15 +60,6 @@ class CreateAssistantPage(BasePage):
|
|
|
71
60
|
)
|
|
72
61
|
)
|
|
73
62
|
|
|
74
|
-
@property
|
|
75
|
-
def cancel_button(self) -> Locator:
|
|
76
|
-
"""Cancel button in header"""
|
|
77
|
-
return (
|
|
78
|
-
self.page.locator('button.button.secondary.medium:has-text("Cancel")')
|
|
79
|
-
or self.page.locator('button:has-text("Cancel")')
|
|
80
|
-
or self.page.locator('.ml-auto button:has-text("Cancel")')
|
|
81
|
-
)
|
|
82
|
-
|
|
83
63
|
@property
|
|
84
64
|
def create_button(self) -> Locator:
|
|
85
65
|
"""Create button with plus icon (primary button)"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import re
|
|
2
2
|
|
|
3
|
-
from playwright.sync_api import expect
|
|
3
|
+
from playwright.sync_api import expect, Locator
|
|
4
4
|
from reportportal_client import step
|
|
5
5
|
|
|
6
6
|
from codemie_test_harness.tests.ui.pageobject.components.menu import Menu
|
|
@@ -15,11 +15,24 @@ class BasePage:
|
|
|
15
15
|
|
|
16
16
|
# Component properties using @property decorator
|
|
17
17
|
@property
|
|
18
|
-
def back_button(self):
|
|
19
|
-
"""Back button in
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
def back_button(self) -> Locator:
|
|
19
|
+
"""Back button in header with arrow icon"""
|
|
20
|
+
return (
|
|
21
|
+
self.page.locator("button.button.secondary.medium").first
|
|
22
|
+
or self.page.locator(
|
|
23
|
+
'button:has(svg[xmlns="http://www.w3.org/2000/svg"])'
|
|
24
|
+
).first
|
|
25
|
+
or self.page.locator(".mr-6 button")
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def cancel_button(self) -> Locator:
|
|
30
|
+
"""Cancel button in header"""
|
|
31
|
+
return (
|
|
32
|
+
self.page.locator('button.button.secondary.medium:has-text("Cancel")')
|
|
33
|
+
or self.page.locator('button:has-text("Cancel")')
|
|
34
|
+
or self.page.locator('.ml-auto button:has-text("Cancel")')
|
|
35
|
+
)
|
|
23
36
|
|
|
24
37
|
@property
|
|
25
38
|
def pop_up(self):
|