codemie-test-harness 0.1.176__py3-none-any.whl → 0.1.178__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 (25) hide show
  1. codemie_test_harness/tests/assistant/tools/mcp/test_single_assistant_dual_time_plugins.py +8 -2
  2. codemie_test_harness/tests/conftest.py +6 -6
  3. codemie_test_harness/tests/llm/assistants/test_lite_llm.py +5 -4
  4. codemie_test_harness/tests/test_data/google_datasource_test_data.py +4 -1
  5. codemie_test_harness/tests/ui/_test_data/datasource_test_data.py +125 -0
  6. codemie_test_harness/tests/ui/datasource/__init__.py +0 -0
  7. codemie_test_harness/tests/ui/datasource/test_create_datasource.py +188 -0
  8. codemie_test_harness/tests/ui/datasource/test_datasource_page.py +61 -0
  9. codemie_test_harness/tests/ui/datasource/test_edit_datasource.py +180 -0
  10. codemie_test_harness/tests/ui/datasource/test_view_datasource.py +220 -0
  11. codemie_test_harness/tests/ui/pageobject/assistants/assistants_page.py +1 -1
  12. codemie_test_harness/tests/ui/pageobject/base_page.py +31 -5
  13. codemie_test_harness/tests/ui/pageobject/components/project_selector.py +116 -0
  14. codemie_test_harness/tests/ui/pageobject/components/workflow_sidebar.py +1 -1
  15. codemie_test_harness/tests/ui/pageobject/datasources/__init__.py +0 -0
  16. codemie_test_harness/tests/ui/pageobject/datasources/create_edit_datasource_page.py +771 -0
  17. codemie_test_harness/tests/ui/pageobject/datasources/datasource_page.py +233 -0
  18. codemie_test_harness/tests/ui/pageobject/datasources/datasource_sidebar.py +303 -0
  19. codemie_test_harness/tests/ui/pageobject/datasources/view_datasource_page.py +335 -0
  20. codemie_test_harness/tests/utils/datasource_utils.py +13 -18
  21. {codemie_test_harness-0.1.176.dist-info → codemie_test_harness-0.1.178.dist-info}/METADATA +2 -2
  22. {codemie_test_harness-0.1.176.dist-info → codemie_test_harness-0.1.178.dist-info}/RECORD +24 -13
  23. codemie_test_harness/tests/ui/pytest.ini +0 -18
  24. {codemie_test_harness-0.1.176.dist-info → codemie_test_harness-0.1.178.dist-info}/WHEEL +0 -0
  25. {codemie_test_harness-0.1.176.dist-info → codemie_test_harness-0.1.178.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,220 @@
1
+ import pytest
2
+
3
+ from codemie_test_harness.tests.ui.pageobject.datasources.view_datasource_page import (
4
+ ViewDatasourcePage,
5
+ )
6
+ from codemie_test_harness.tests.ui.pageobject.datasources.datasource_page import (
7
+ DataSourcePage,
8
+ )
9
+ from tests import PROJECT, TEST_USER
10
+ from tests.test_data.google_datasource_test_data import GOOGLE_DOC_URL
11
+
12
+ from tests.ui._test_data.datasource_test_data import (
13
+ TITLE_VIEW_DATASOURCE,
14
+ SUBTITLE_VIEW_DATASOURCE,
15
+ DataSourceStatus,
16
+ DataSourceType,
17
+ DataSourceFilterType,
18
+ )
19
+ from tests.utils.constants import FILES_PATH
20
+
21
+
22
+ @pytest.mark.datasource_ui
23
+ @pytest.mark.ui
24
+ def test_view_git_datasource_page(
25
+ page, datasource_utils, git_integration, default_embedding_llm, client
26
+ ):
27
+ """Test that all main View Datasource page elements are visible."""
28
+ datasource_page = DataSourcePage(page)
29
+ view_page = ViewDatasourcePage(page)
30
+ datasource = datasource_utils.create_gitlab_datasource(
31
+ setting_id=git_integration.id,
32
+ embeddings_model=default_embedding_llm.base_name,
33
+ )
34
+
35
+ datasource_page.navigate_to()
36
+ datasource_page.should_see_table_row_with_values(
37
+ name=datasource.name,
38
+ status=DataSourceStatus.COMPLETED,
39
+ project=PROJECT,
40
+ type_=DataSourceFilterType.CODE,
41
+ created_by=TEST_USER,
42
+ )
43
+
44
+ datasource_page.click_datasource_row_by_name(datasource.name)
45
+ view_page.sidebar.should_see_title_subtitle(
46
+ TITLE_VIEW_DATASOURCE, SUBTITLE_VIEW_DATASOURCE
47
+ )
48
+ view_page.should_see_ds_name_and_owner(
49
+ datasource_name=datasource.name, owner=TEST_USER
50
+ )
51
+ view_page.should_see_description(description=datasource.description)
52
+ view_page.should_see_processing_summary(is_git=True)
53
+ view_page.should_see_overview(
54
+ project=PROJECT, ds_type=DataSourceType.GIT, ds_id=datasource.id
55
+ )
56
+ view_page.should_see_configuration(
57
+ embeddings_model=default_embedding_llm.label,
58
+ summarization_model=client.llms.list()[3].label,
59
+ )
60
+ view_page.should_open_and_see_processed_data()
61
+
62
+
63
+ @pytest.mark.datasource_ui
64
+ @pytest.mark.ui
65
+ def test_view_confluence_datasource_page(
66
+ page, datasource_utils, confluence_integration, default_embedding_llm, client
67
+ ):
68
+ """Test that all main View Datasource page elements are visible."""
69
+ datasource_page = DataSourcePage(page)
70
+ view_page = ViewDatasourcePage(page)
71
+ datasource = datasource_utils.create_confluence_datasource(
72
+ setting_id=confluence_integration.id,
73
+ )
74
+
75
+ datasource_page.navigate_to()
76
+ datasource_page.should_see_table_row_with_values(
77
+ name=datasource.name,
78
+ status=DataSourceStatus.COMPLETED,
79
+ project=PROJECT,
80
+ type_=DataSourceFilterType.CONFLUENCE,
81
+ created_by=TEST_USER,
82
+ )
83
+
84
+ datasource_page.click_datasource_row_by_name(datasource.name)
85
+ view_page.sidebar.should_see_title_subtitle(
86
+ TITLE_VIEW_DATASOURCE, SUBTITLE_VIEW_DATASOURCE
87
+ )
88
+ view_page.should_see_ds_name_and_owner(
89
+ datasource_name=datasource.name, owner=TEST_USER
90
+ )
91
+ view_page.should_see_description(description=datasource.description)
92
+ view_page.should_see_processing_summary()
93
+ view_page.should_see_overview(
94
+ project=PROJECT, ds_type=DataSourceFilterType.CONFLUENCE, ds_id=datasource.id
95
+ )
96
+ view_page.should_see_configuration(
97
+ embeddings_model=default_embedding_llm.label,
98
+ summarization_model=client.llms.list()[3].label,
99
+ )
100
+ view_page.should_see_processed_data()
101
+
102
+
103
+ @pytest.mark.datasource_ui
104
+ @pytest.mark.ui
105
+ def test_view_jira_datasource_page(
106
+ page, datasource_utils, jira_integration, default_embedding_llm, client
107
+ ):
108
+ """Test that all main View Datasource page elements are visible."""
109
+ datasource_page = DataSourcePage(page)
110
+ view_page = ViewDatasourcePage(page)
111
+ datasource = datasource_utils.create_jira_datasource(
112
+ setting_id=jira_integration.id,
113
+ )
114
+
115
+ datasource_page.navigate_to()
116
+ datasource_page.should_see_table_row_with_values(
117
+ name=datasource.name,
118
+ status=DataSourceStatus.COMPLETED,
119
+ project=PROJECT,
120
+ type_=DataSourceFilterType.JIRA,
121
+ created_by=TEST_USER,
122
+ )
123
+
124
+ datasource_page.click_datasource_row_by_name(datasource.name)
125
+ view_page.sidebar.should_see_title_subtitle(
126
+ TITLE_VIEW_DATASOURCE, SUBTITLE_VIEW_DATASOURCE
127
+ )
128
+ view_page.should_see_ds_name_and_owner(
129
+ datasource_name=datasource.name, owner=TEST_USER
130
+ )
131
+ view_page.should_see_description(description=datasource.description)
132
+ view_page.should_see_processing_summary()
133
+ view_page.should_see_overview(
134
+ project=PROJECT, ds_type=DataSourceFilterType.JIRA, ds_id=datasource.id
135
+ )
136
+ view_page.should_see_configuration(
137
+ embeddings_model=default_embedding_llm.label,
138
+ summarization_model=client.llms.list()[3].label,
139
+ )
140
+ view_page.should_see_processed_data()
141
+
142
+
143
+ @pytest.mark.datasource_ui
144
+ @pytest.mark.ui
145
+ def test_view_file_datasource_page(
146
+ page, datasource_utils, default_embedding_llm, client
147
+ ):
148
+ """Test that all main View Datasource page elements are visible."""
149
+ datasource_page = DataSourcePage(page)
150
+ view_page = ViewDatasourcePage(page)
151
+ datasource = datasource_utils.create_file_datasource(
152
+ files=[str(FILES_PATH / "test.txt")],
153
+ )
154
+
155
+ datasource_page.navigate_to()
156
+ datasource_page.should_see_table_row_with_values(
157
+ name=datasource.name,
158
+ status=DataSourceStatus.COMPLETED,
159
+ project=PROJECT,
160
+ type_=DataSourceFilterType.FILE,
161
+ created_by=TEST_USER,
162
+ )
163
+
164
+ datasource_page.click_datasource_row_by_name(datasource.name)
165
+ view_page.sidebar.should_see_title_subtitle(
166
+ TITLE_VIEW_DATASOURCE, SUBTITLE_VIEW_DATASOURCE
167
+ )
168
+ view_page.should_see_ds_name_and_owner(
169
+ datasource_name=datasource.name, owner=TEST_USER
170
+ )
171
+ view_page.should_see_description(description=datasource.description)
172
+ view_page.should_see_processing_summary()
173
+ view_page.should_see_overview(
174
+ project=PROJECT, ds_type=DataSourceFilterType.FILE, ds_id=datasource.id
175
+ )
176
+ view_page.should_see_configuration(
177
+ embeddings_model=default_embedding_llm.label,
178
+ summarization_model=client.llms.list()[3].label,
179
+ )
180
+ view_page.should_see_processed_data()
181
+
182
+
183
+ @pytest.mark.datasource_ui
184
+ @pytest.mark.ui
185
+ def test_view_google_datasource_page(
186
+ page, datasource_utils, default_embedding_llm, client
187
+ ):
188
+ """Test that all main View Datasource page elements are visible."""
189
+ datasource_page = DataSourcePage(page)
190
+ view_page = ViewDatasourcePage(page)
191
+ datasource = datasource_utils.create_google_doc_datasource(
192
+ google_doc=GOOGLE_DOC_URL,
193
+ )
194
+
195
+ datasource_page.navigate_to()
196
+ datasource_page.should_see_table_row_with_values(
197
+ name=datasource.name,
198
+ status=DataSourceStatus.COMPLETED,
199
+ project=PROJECT,
200
+ type_=DataSourceFilterType.GOOGLE,
201
+ created_by=TEST_USER,
202
+ )
203
+
204
+ datasource_page.click_datasource_row_by_name(datasource.name)
205
+ view_page.sidebar.should_see_title_subtitle(
206
+ TITLE_VIEW_DATASOURCE, SUBTITLE_VIEW_DATASOURCE
207
+ )
208
+ view_page.should_see_ds_name_and_owner(
209
+ datasource_name=datasource.name, owner=TEST_USER
210
+ )
211
+ view_page.should_see_description(description=datasource.description)
212
+ view_page.should_see_processing_summary()
213
+ view_page.should_see_overview(
214
+ project=PROJECT, ds_type=DataSourceFilterType.GOOGLE, ds_id=datasource.id
215
+ )
216
+ view_page.should_see_configuration(
217
+ embeddings_model=default_embedding_llm.label,
218
+ summarization_model=client.llms.list()[3].label,
219
+ )
220
+ view_page.should_see_processed_data()
@@ -26,7 +26,7 @@ class AssistantsPage(BasePage):
26
26
  @property
27
27
  def create_assistant_button(self):
28
28
  """Create new assistant button."""
29
- return self.page.locator('button:has-text("Create Assistant")')
29
+ return self.page.locator("button").filter(has_text="Create Assistant")
30
30
 
31
31
  @property
32
32
  def search_input(self):
@@ -28,11 +28,12 @@ class BasePage:
28
28
  @property
29
29
  def cancel_button(self) -> Locator:
30
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
- )
31
+ return self.page.locator("button").filter(has_text="Cancel")
32
+
33
+ @property
34
+ def create_button(self) -> Locator:
35
+ """Cancel button in header"""
36
+ return self.page.locator("button").filter(has_text="Create")
36
37
 
37
38
  @property
38
39
  def pop_up(self):
@@ -65,6 +66,31 @@ class BasePage:
65
66
  """Main page content area."""
66
67
  return self.page.locator("main, .main-content")
67
68
 
69
+ @property
70
+ def pagination_block(self):
71
+ """Pagination panel at the bottom."""
72
+ return self.page.locator("div.text-text-secondary.text-h5").filter(
73
+ has_text="Page: "
74
+ )
75
+
76
+ def pagination_page_button(self, page_number: int):
77
+ """Pagination numbered page button."""
78
+ return self.page.locator("span.px-2.flex.justify-center").filter(
79
+ has_text=str(page_number)
80
+ )
81
+
82
+ @property
83
+ def show_per_page_label(self):
84
+ """Show per-page label."""
85
+ return self.page.locator("div.text-text-secondary.text-h5").filter(
86
+ has_text="Show:"
87
+ )
88
+
89
+ @property
90
+ def show_per_page_dropdown(self):
91
+ """Show-per-page select in pagination."""
92
+ return self.page.locator("#per-page")
93
+
68
94
  # Navigation methods
69
95
  @step
70
96
  def go_to_workflows_page(self):
@@ -0,0 +1,116 @@
1
+ from playwright.sync_api import expect
2
+ from reportportal_client import step
3
+
4
+
5
+ class ProjectSelector:
6
+ """Component representing the project selector on different create pages."""
7
+
8
+ def __init__(self, page):
9
+ """
10
+ Initialize project selector object.
11
+
12
+ Args:
13
+ page: Playwright page object
14
+ """
15
+ self.page = page
16
+
17
+ @property
18
+ def project_multiselect(self):
19
+ return self.page.locator("#project-selector")
20
+
21
+ @property
22
+ def disabled_project_multiselect(self):
23
+ return self.page.locator("#project-selector.p-disabled")
24
+
25
+ @property
26
+ def disabled_project_multiselect_value(self):
27
+ return self.disabled_project_multiselect.locator("input")
28
+
29
+ @property
30
+ def project_multiselect_value(self):
31
+ return self.page.locator("div.p-multiselect-label")
32
+
33
+ @property
34
+ def project_multiselect_input(self):
35
+ return self.page.locator("input.p-multiselect-filter.p-inputtext.p-component")
36
+
37
+ @property
38
+ def project_multiselect_top_three(self):
39
+ return self.page.locator("div.p-multiselect-items-wrapper ul li")
40
+
41
+ @property
42
+ def project_multiselect_top_three_checkbox(self):
43
+ return self.project_multiselect_top_three.locator("input")
44
+
45
+ @property
46
+ def project_multiselect_top_three__value(self):
47
+ return self.project_multiselect_top_three.locator("span")
48
+
49
+ # ----------------------------------
50
+ # Verification Methods
51
+ # ----------------------------------
52
+
53
+ @step
54
+ def should_see_multiselect(self):
55
+ """Asserts the selector widget is present and visible."""
56
+ expect(self.project_multiselect).to_be_visible()
57
+ return self
58
+
59
+ @step
60
+ def should_see_multiselect_input(self):
61
+ """Asserts the filter/search input is visible (after opening dropdown)."""
62
+ expect(self.project_multiselect_input).to_be_visible()
63
+ return self
64
+
65
+ @step
66
+ def should_have_selected(self, project_name: str):
67
+ """Asserts that project_name is shown as the selected project."""
68
+ expect(self.project_multiselect_value).to_have_text(project_name)
69
+ return self
70
+
71
+ @step
72
+ def should_see_disabled_multiselect(self, project_name: str):
73
+ """Asserts that project selector is disabled."""
74
+ expect(self.disabled_project_multiselect).to_be_visible()
75
+ expect(self.disabled_project_multiselect_value).to_have_value(project_name)
76
+ return self
77
+
78
+ # ----------------------------------
79
+ # Interaction Methods
80
+ # ----------------------------------
81
+
82
+ @step
83
+ def open(self):
84
+ """Clicks to open the multiselect project dropdown."""
85
+ self.project_multiselect.click()
86
+ return self
87
+
88
+ @step
89
+ def search_for(self, text: str):
90
+ """
91
+ Types in the project multiselect input to filter/search projects.
92
+ Dropdown must be open first.
93
+ """
94
+ self.should_see_multiselect_input()
95
+ self.project_multiselect_input.fill(text)
96
+ return self
97
+
98
+ @step
99
+ def select_by_text(self, text: str):
100
+ """
101
+ Selects a project by its visible text.
102
+ Dropdown must be open and filtered unless all options are visible.
103
+ """
104
+ self.page.get_by_text(text, exact=True).click()
105
+
106
+ return self
107
+
108
+ @step
109
+ def search_and_select_project(self, project_name: str):
110
+ (
111
+ self.open()
112
+ .search_for(project_name)
113
+ .select_by_text(project_name)
114
+ .should_have_selected(project_name)
115
+ )
116
+ return self
@@ -18,7 +18,7 @@ class WorkflowSidebar:
18
18
  @property
19
19
  def sidebar_container(self):
20
20
  """Main sidebar container."""
21
- return self.page.locator("aside.bg-sidebar")
21
+ return self.page.locator("aside.bg-sidebar-gradient")
22
22
 
23
23
  @property
24
24
  def page_title(self):