codemie-test-harness 0.1.177__py3-none-any.whl → 0.1.179__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 (28) hide show
  1. codemie_test_harness/tests/assistant/default_integrations/test_default_integrations_for_tool_kit.py +2 -2
  2. codemie_test_harness/tests/test_data/ado_work_item_tools_test_data.py +3 -3
  3. codemie_test_harness/tests/test_data/google_datasource_test_data.py +4 -1
  4. codemie_test_harness/tests/ui/_test_data/datasource_test_data.py +125 -0
  5. codemie_test_harness/tests/ui/datasource/__init__.py +0 -0
  6. codemie_test_harness/tests/ui/datasource/test_create_datasource.py +191 -0
  7. codemie_test_harness/tests/ui/datasource/test_datasource_page.py +61 -0
  8. codemie_test_harness/tests/ui/datasource/test_edit_datasource.py +184 -0
  9. codemie_test_harness/tests/ui/datasource/test_view_datasource.py +222 -0
  10. codemie_test_harness/tests/ui/pageobject/assistants/assistants_page.py +1 -1
  11. codemie_test_harness/tests/ui/pageobject/base_page.py +31 -5
  12. codemie_test_harness/tests/ui/pageobject/components/project_selector.py +116 -0
  13. codemie_test_harness/tests/ui/pageobject/components/workflow_sidebar.py +1 -1
  14. codemie_test_harness/tests/ui/pageobject/datasources/__init__.py +0 -0
  15. codemie_test_harness/tests/ui/pageobject/datasources/create_edit_datasource_page.py +778 -0
  16. codemie_test_harness/tests/ui/pageobject/datasources/datasource_page.py +237 -0
  17. codemie_test_harness/tests/ui/pageobject/datasources/datasource_sidebar.py +303 -0
  18. codemie_test_harness/tests/ui/pageobject/datasources/view_datasource_page.py +337 -0
  19. codemie_test_harness/tests/utils/datasource_utils.py +13 -18
  20. codemie_test_harness/tests/workflow/assistant_tools/default_integrations/test_default_integrations_for_tool_kit.py +2 -2
  21. codemie_test_harness/tests/workflow/direct_tools_calling/test_workflow_with_vcs_tools.py +2 -0
  22. codemie_test_harness/tests/workflow/virtual_assistant_tools/default_integrations/test_default_integrations_for_tool_kit.py +2 -2
  23. {codemie_test_harness-0.1.177.dist-info → codemie_test_harness-0.1.179.dist-info}/METADATA +2 -2
  24. {codemie_test_harness-0.1.177.dist-info → codemie_test_harness-0.1.179.dist-info}/RECORD +27 -16
  25. codemie_test_harness/tests/ui/pytest.ini +0 -18
  26. /codemie_test_harness/tests/assistant/tools/{mcp → plugin}/test_single_assistant_dual_time_plugins.py +0 -0
  27. {codemie_test_harness-0.1.177.dist-info → codemie_test_harness-0.1.179.dist-info}/WHEEL +0 -0
  28. {codemie_test_harness-0.1.177.dist-info → codemie_test_harness-0.1.179.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,222 @@
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 codemie_test_harness.tests import PROJECT, TEST_USER
10
+ from codemie_test_harness.tests.test_data.google_datasource_test_data import (
11
+ GOOGLE_DOC_URL,
12
+ )
13
+
14
+ from codemie_test_harness.tests.ui._test_data.datasource_test_data import (
15
+ TITLE_VIEW_DATASOURCE,
16
+ SUBTITLE_VIEW_DATASOURCE,
17
+ DataSourceStatus,
18
+ DataSourceType,
19
+ DataSourceFilterType,
20
+ )
21
+ from codemie_test_harness.tests.utils.constants import FILES_PATH
22
+
23
+
24
+ @pytest.mark.datasource_ui
25
+ @pytest.mark.ui
26
+ def test_view_git_datasource_page(
27
+ page, datasource_utils, git_integration, default_embedding_llm, client
28
+ ):
29
+ """Test that all main View Datasource page elements are visible."""
30
+ datasource_page = DataSourcePage(page)
31
+ view_page = ViewDatasourcePage(page)
32
+ datasource = datasource_utils.create_gitlab_datasource(
33
+ setting_id=git_integration.id,
34
+ embeddings_model=default_embedding_llm.base_name,
35
+ )
36
+
37
+ datasource_page.navigate_to()
38
+ datasource_page.should_see_table_row_with_values(
39
+ name=datasource.name,
40
+ status=DataSourceStatus.COMPLETED,
41
+ project=PROJECT,
42
+ type_=DataSourceFilterType.CODE,
43
+ created_by=TEST_USER,
44
+ )
45
+
46
+ datasource_page.click_datasource_row_by_name(datasource.name)
47
+ view_page.sidebar.should_see_title_subtitle(
48
+ TITLE_VIEW_DATASOURCE, SUBTITLE_VIEW_DATASOURCE
49
+ )
50
+ view_page.should_see_ds_name_and_owner(
51
+ datasource_name=datasource.name, owner=TEST_USER
52
+ )
53
+ view_page.should_see_description(description=datasource.description)
54
+ view_page.should_see_processing_summary(is_git=True)
55
+ view_page.should_see_overview(
56
+ project=PROJECT, ds_type=DataSourceType.GIT, ds_id=datasource.id
57
+ )
58
+ view_page.should_see_configuration(
59
+ embeddings_model=default_embedding_llm.label,
60
+ summarization_model=client.llms.list()[3].label,
61
+ )
62
+ view_page.should_open_and_see_processed_data()
63
+
64
+
65
+ @pytest.mark.datasource_ui
66
+ @pytest.mark.ui
67
+ def test_view_confluence_datasource_page(
68
+ page, datasource_utils, confluence_integration, default_embedding_llm, client
69
+ ):
70
+ """Test that all main View Datasource page elements are visible."""
71
+ datasource_page = DataSourcePage(page)
72
+ view_page = ViewDatasourcePage(page)
73
+ datasource = datasource_utils.create_confluence_datasource(
74
+ setting_id=confluence_integration.id,
75
+ )
76
+
77
+ datasource_page.navigate_to()
78
+ datasource_page.should_see_table_row_with_values(
79
+ name=datasource.name,
80
+ status=DataSourceStatus.COMPLETED,
81
+ project=PROJECT,
82
+ type_=DataSourceFilterType.CONFLUENCE,
83
+ created_by=TEST_USER,
84
+ )
85
+
86
+ datasource_page.click_datasource_row_by_name(datasource.name)
87
+ view_page.sidebar.should_see_title_subtitle(
88
+ TITLE_VIEW_DATASOURCE, SUBTITLE_VIEW_DATASOURCE
89
+ )
90
+ view_page.should_see_ds_name_and_owner(
91
+ datasource_name=datasource.name, owner=TEST_USER
92
+ )
93
+ view_page.should_see_description(description=datasource.description)
94
+ view_page.should_see_processing_summary()
95
+ view_page.should_see_overview(
96
+ project=PROJECT, ds_type=DataSourceFilterType.CONFLUENCE, ds_id=datasource.id
97
+ )
98
+ view_page.should_see_configuration(
99
+ embeddings_model=default_embedding_llm.label,
100
+ summarization_model=client.llms.list()[3].label,
101
+ )
102
+ view_page.should_see_processed_data()
103
+
104
+
105
+ @pytest.mark.datasource_ui
106
+ @pytest.mark.ui
107
+ def test_view_jira_datasource_page(
108
+ page, datasource_utils, jira_integration, default_embedding_llm, client
109
+ ):
110
+ """Test that all main View Datasource page elements are visible."""
111
+ datasource_page = DataSourcePage(page)
112
+ view_page = ViewDatasourcePage(page)
113
+ datasource = datasource_utils.create_jira_datasource(
114
+ setting_id=jira_integration.id,
115
+ )
116
+
117
+ datasource_page.navigate_to()
118
+ datasource_page.should_see_table_row_with_values(
119
+ name=datasource.name,
120
+ status=DataSourceStatus.COMPLETED,
121
+ project=PROJECT,
122
+ type_=DataSourceFilterType.JIRA,
123
+ created_by=TEST_USER,
124
+ )
125
+
126
+ datasource_page.click_datasource_row_by_name(datasource.name)
127
+ view_page.sidebar.should_see_title_subtitle(
128
+ TITLE_VIEW_DATASOURCE, SUBTITLE_VIEW_DATASOURCE
129
+ )
130
+ view_page.should_see_ds_name_and_owner(
131
+ datasource_name=datasource.name, owner=TEST_USER
132
+ )
133
+ view_page.should_see_description(description=datasource.description)
134
+ view_page.should_see_processing_summary()
135
+ view_page.should_see_overview(
136
+ project=PROJECT, ds_type=DataSourceFilterType.JIRA, ds_id=datasource.id
137
+ )
138
+ view_page.should_see_configuration(
139
+ embeddings_model=default_embedding_llm.label,
140
+ summarization_model=client.llms.list()[3].label,
141
+ )
142
+ view_page.should_see_processed_data()
143
+
144
+
145
+ @pytest.mark.datasource_ui
146
+ @pytest.mark.ui
147
+ def test_view_file_datasource_page(
148
+ page, datasource_utils, default_embedding_llm, client
149
+ ):
150
+ """Test that all main View Datasource page elements are visible."""
151
+ datasource_page = DataSourcePage(page)
152
+ view_page = ViewDatasourcePage(page)
153
+ datasource = datasource_utils.create_file_datasource(
154
+ files=[str(FILES_PATH / "test.txt")],
155
+ )
156
+
157
+ datasource_page.navigate_to()
158
+ datasource_page.should_see_table_row_with_values(
159
+ name=datasource.name,
160
+ status=DataSourceStatus.COMPLETED,
161
+ project=PROJECT,
162
+ type_=DataSourceFilterType.FILE,
163
+ created_by=TEST_USER,
164
+ )
165
+
166
+ datasource_page.click_datasource_row_by_name(datasource.name)
167
+ view_page.sidebar.should_see_title_subtitle(
168
+ TITLE_VIEW_DATASOURCE, SUBTITLE_VIEW_DATASOURCE
169
+ )
170
+ view_page.should_see_ds_name_and_owner(
171
+ datasource_name=datasource.name, owner=TEST_USER
172
+ )
173
+ view_page.should_see_description(description=datasource.description)
174
+ view_page.should_see_processing_summary()
175
+ view_page.should_see_overview(
176
+ project=PROJECT, ds_type=DataSourceFilterType.FILE, ds_id=datasource.id
177
+ )
178
+ view_page.should_see_configuration(
179
+ embeddings_model=default_embedding_llm.label,
180
+ summarization_model=client.llms.list()[3].label,
181
+ )
182
+ view_page.should_see_processed_data()
183
+
184
+
185
+ @pytest.mark.datasource_ui
186
+ @pytest.mark.ui
187
+ def test_view_google_datasource_page(
188
+ page, datasource_utils, default_embedding_llm, client
189
+ ):
190
+ """Test that all main View Datasource page elements are visible."""
191
+ datasource_page = DataSourcePage(page)
192
+ view_page = ViewDatasourcePage(page)
193
+ datasource = datasource_utils.create_google_doc_datasource(
194
+ google_doc=GOOGLE_DOC_URL,
195
+ )
196
+
197
+ datasource_page.navigate_to()
198
+ datasource_page.should_see_table_row_with_values(
199
+ name=datasource.name,
200
+ status=DataSourceStatus.COMPLETED,
201
+ project=PROJECT,
202
+ type_=DataSourceFilterType.GOOGLE,
203
+ created_by=TEST_USER,
204
+ )
205
+
206
+ datasource_page.click_datasource_row_by_name(datasource.name)
207
+ view_page.sidebar.should_see_title_subtitle(
208
+ TITLE_VIEW_DATASOURCE, SUBTITLE_VIEW_DATASOURCE
209
+ )
210
+ view_page.should_see_ds_name_and_owner(
211
+ datasource_name=datasource.name, owner=TEST_USER
212
+ )
213
+ view_page.should_see_description(description=datasource.description)
214
+ view_page.should_see_processing_summary()
215
+ view_page.should_see_overview(
216
+ project=PROJECT, ds_type=DataSourceFilterType.GOOGLE, ds_id=datasource.id
217
+ )
218
+ view_page.should_see_configuration(
219
+ embeddings_model=default_embedding_llm.label,
220
+ summarization_model=client.llms.list()[3].label,
221
+ )
222
+ 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):