codemie-test-harness 0.1.166__py3-none-any.whl → 0.1.168__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/tests/assistant/tools/mcp/test_single_assistant_dual_time_plugins.py +160 -0
- codemie_test_harness/tests/test_data/plugin_tools_test_data.py +33 -0
- codemie_test_harness/tests/ui/pageobject/base_page.py +24 -24
- codemie_test_harness/tests/ui/pageobject/components/__init__.py +2 -2
- codemie_test_harness/tests/ui/pageobject/components/execution_history_row.py +3 -3
- codemie_test_harness/tests/ui/pageobject/components/{header.py → menu.py} +57 -111
- codemie_test_harness/tests/ui/pageobject/components/pop_up.py +2 -2
- codemie_test_harness/tests/ui/pageobject/components/workflow_card.py +7 -10
- codemie_test_harness/tests/ui/pageobject/components/workflow_execution_history_item.py +9 -9
- codemie_test_harness/tests/ui/pageobject/components/workflow_execution_state.py +1 -1
- codemie_test_harness/tests/ui/pageobject/components/workflow_sidebar.py +16 -16
- codemie_test_harness/tests/ui/pageobject/workflows/base_workflow_form_page.py +32 -65
- codemie_test_harness/tests/ui/pageobject/workflows/create_workflow_page.py +4 -4
- codemie_test_harness/tests/ui/pageobject/workflows/edit_workflow_page.py +6 -4
- codemie_test_harness/tests/ui/pageobject/workflows/workflow_details_page.py +32 -61
- codemie_test_harness/tests/ui/pageobject/workflows/workflow_executions_page.py +17 -23
- codemie_test_harness/tests/ui/pageobject/workflows/workflow_template_details.py +5 -11
- codemie_test_harness/tests/ui/pageobject/workflows/workflow_templates_page.py +5 -2
- codemie_test_harness/tests/ui/pageobject/workflows/workflows_page.py +3 -5
- codemie_test_harness/tests/ui/workflows/__init__.py +0 -0
- codemie_test_harness/tests/ui/{test_create_workflow.py → workflows/test_create_workflow.py} +12 -33
- codemie_test_harness/tests/ui/{test_edit_workflow.py → workflows/test_edit_workflow.py} +14 -34
- codemie_test_harness/tests/ui/{test_workflow_details.py → workflows/test_workflow_details.py} +11 -11
- codemie_test_harness/tests/ui/{test_workflow_executions_page.py → workflows/test_workflow_executions_page.py} +0 -2
- codemie_test_harness/tests/ui/{test_workflow_templates.py → workflows/test_workflow_templates.py} +0 -2
- codemie_test_harness/tests/ui/{test_workflows.py → workflows/test_workflows.py} +8 -6
- {codemie_test_harness-0.1.166.dist-info → codemie_test_harness-0.1.168.dist-info}/METADATA +2 -2
- {codemie_test_harness-0.1.166.dist-info → codemie_test_harness-0.1.168.dist-info}/RECORD +30 -28
- {codemie_test_harness-0.1.166.dist-info → codemie_test_harness-0.1.168.dist-info}/WHEEL +0 -0
- {codemie_test_harness-0.1.166.dist-info → codemie_test_harness-0.1.168.dist-info}/entry_points.txt +0 -0
|
@@ -26,17 +26,17 @@ class WorkflowCard:
|
|
|
26
26
|
@property
|
|
27
27
|
def title(self):
|
|
28
28
|
"""Workflow title element."""
|
|
29
|
-
return self.card.locator(".
|
|
29
|
+
return self.card.locator(".whitespace-nowrap.truncate.font-semibold")
|
|
30
30
|
|
|
31
31
|
@property
|
|
32
32
|
def author(self):
|
|
33
33
|
"""Workflow author element."""
|
|
34
|
-
return self.card.locator(".text-
|
|
34
|
+
return self.card.locator(".text-xs.text-text-gray-300")
|
|
35
35
|
|
|
36
36
|
@property
|
|
37
37
|
def description(self):
|
|
38
38
|
"""Workflow description element."""
|
|
39
|
-
return self.card.locator("p.text-
|
|
39
|
+
return self.card.locator(".flex-row p.text-xs")
|
|
40
40
|
|
|
41
41
|
@property
|
|
42
42
|
def description_tooltip(self):
|
|
@@ -48,7 +48,7 @@ class WorkflowCard:
|
|
|
48
48
|
@property
|
|
49
49
|
def run_button(self):
|
|
50
50
|
"""Run workflow button."""
|
|
51
|
-
return self.card.locator("button.
|
|
51
|
+
return self.card.locator("button.gradient.medium")
|
|
52
52
|
|
|
53
53
|
@property
|
|
54
54
|
def menu_button(self):
|
|
@@ -137,20 +137,17 @@ class WorkflowCard:
|
|
|
137
137
|
@step
|
|
138
138
|
def should_have_title(self, expected_title: str):
|
|
139
139
|
"""Verify the workflow has the expected title."""
|
|
140
|
-
|
|
141
|
-
return self
|
|
140
|
+
return self.get_title() == expected_title
|
|
142
141
|
|
|
143
142
|
@step
|
|
144
143
|
def should_have_author(self, expected_author: str):
|
|
145
144
|
"""Verify the workflow has the expected author."""
|
|
146
|
-
|
|
147
|
-
return self
|
|
145
|
+
return self.get_author() == expected_author
|
|
148
146
|
|
|
149
147
|
@step
|
|
150
148
|
def should_have_description(self, expected_description: str):
|
|
151
149
|
"""Verify the workflow has the expected description."""
|
|
152
|
-
|
|
153
|
-
return self
|
|
150
|
+
return self.get_description() == expected_description
|
|
154
151
|
|
|
155
152
|
@step
|
|
156
153
|
def should_be_shared_with_project(self):
|
|
@@ -25,12 +25,12 @@ class WorkflowExecutionHistoryItem:
|
|
|
25
25
|
@property
|
|
26
26
|
def status_badge(self):
|
|
27
27
|
"""Status badge (Succeeded/Failed/Running)."""
|
|
28
|
-
return self.item.locator(".flex.flex-row.items-center.
|
|
28
|
+
return self.item.locator(".flex.flex-row.items-center.border")
|
|
29
29
|
|
|
30
30
|
@property
|
|
31
31
|
def status_dot(self):
|
|
32
32
|
"""Status indicator dot."""
|
|
33
|
-
return self.status_badge.locator(".rounded-full.
|
|
33
|
+
return self.status_badge.locator(".rounded-full.inline-block")
|
|
34
34
|
|
|
35
35
|
@property
|
|
36
36
|
def timestamp(self):
|
|
@@ -38,8 +38,8 @@ class WorkflowExecutionHistoryItem:
|
|
|
38
38
|
return self.item.locator(".text-text-tertiary.text-xs span")
|
|
39
39
|
|
|
40
40
|
@property
|
|
41
|
-
def
|
|
42
|
-
"""Execution
|
|
41
|
+
def execution_body(self):
|
|
42
|
+
"""Execution body text element."""
|
|
43
43
|
return self.item.locator(
|
|
44
44
|
".truncate.overflow-hidden.whitespace-nowrap.min-w-0.text-sm"
|
|
45
45
|
)
|
|
@@ -47,7 +47,7 @@ class WorkflowExecutionHistoryItem:
|
|
|
47
47
|
@property
|
|
48
48
|
def menu_button(self):
|
|
49
49
|
"""Three dots menu button."""
|
|
50
|
-
return self.item.locator(
|
|
50
|
+
return self.item.locator("button.tertiary.medium.m-1")
|
|
51
51
|
|
|
52
52
|
# Utility methods
|
|
53
53
|
@step
|
|
@@ -58,7 +58,7 @@ class WorkflowExecutionHistoryItem:
|
|
|
58
58
|
@step
|
|
59
59
|
def get_execution_id_text(self) -> str:
|
|
60
60
|
"""Get execution ID text."""
|
|
61
|
-
return self.
|
|
61
|
+
return self.execution_body.text_content().strip()
|
|
62
62
|
|
|
63
63
|
@step
|
|
64
64
|
def get_timestamp_text(self) -> str:
|
|
@@ -162,13 +162,13 @@ class WorkflowExecutionHistoryItem:
|
|
|
162
162
|
@step
|
|
163
163
|
def should_have_execution_id(self, expected_id: str):
|
|
164
164
|
"""Verify the execution ID."""
|
|
165
|
-
expect(self.
|
|
165
|
+
expect(self.execution_body).to_have_text(expected_id)
|
|
166
166
|
return self
|
|
167
167
|
|
|
168
168
|
@step
|
|
169
169
|
def should_have_execution_id_pattern(self, pattern: str):
|
|
170
170
|
"""Verify the execution ID matches a pattern (regex)."""
|
|
171
|
-
expect(self.
|
|
171
|
+
expect(self.execution_body).to_match(pattern)
|
|
172
172
|
return self
|
|
173
173
|
|
|
174
174
|
@step
|
|
@@ -213,7 +213,7 @@ class WorkflowExecutionHistoryItem:
|
|
|
213
213
|
"""Verify all main elements are visible."""
|
|
214
214
|
expect(self.container).to_be_visible()
|
|
215
215
|
expect(self.status_badge).to_be_visible()
|
|
216
|
-
expect(self.
|
|
216
|
+
expect(self.execution_body).to_be_visible()
|
|
217
217
|
expect(self.timestamp).to_be_visible()
|
|
218
218
|
expect(self.menu_button).to_be_visible()
|
|
219
219
|
return self
|
|
@@ -97,7 +97,7 @@ class WorkflowExecutionState:
|
|
|
97
97
|
@property
|
|
98
98
|
def expanded_content(self):
|
|
99
99
|
"""Expanded content container (when state is expanded)."""
|
|
100
|
-
return self.state.locator("div.
|
|
100
|
+
return self.state.locator("div.markdown")
|
|
101
101
|
|
|
102
102
|
@property
|
|
103
103
|
def expanded_message(self):
|
|
@@ -14,7 +14,7 @@ class WorkflowSidebar:
|
|
|
14
14
|
"""
|
|
15
15
|
self.page = page
|
|
16
16
|
|
|
17
|
-
# Main container and
|
|
17
|
+
# Main container and sidebar
|
|
18
18
|
@property
|
|
19
19
|
def sidebar_container(self):
|
|
20
20
|
"""Main sidebar container."""
|
|
@@ -57,8 +57,8 @@ class WorkflowSidebar:
|
|
|
57
57
|
|
|
58
58
|
# Filters section
|
|
59
59
|
@property
|
|
60
|
-
def
|
|
61
|
-
"""Filters section
|
|
60
|
+
def filters_sidebar(self):
|
|
61
|
+
"""Filters section sidebar."""
|
|
62
62
|
return self.sidebar_container.locator('span:has-text("Filters")')
|
|
63
63
|
|
|
64
64
|
@property
|
|
@@ -73,8 +73,8 @@ class WorkflowSidebar:
|
|
|
73
73
|
|
|
74
74
|
# Project filter section
|
|
75
75
|
@property
|
|
76
|
-
def
|
|
77
|
-
"""Project filter expandable
|
|
76
|
+
def project_filter_sidebar(self):
|
|
77
|
+
"""Project filter expandable sidebar."""
|
|
78
78
|
return self.sidebar_container.locator('a:has-text("project")')
|
|
79
79
|
|
|
80
80
|
@property
|
|
@@ -110,8 +110,8 @@ class WorkflowSidebar:
|
|
|
110
110
|
|
|
111
111
|
# Shared filter section
|
|
112
112
|
@property
|
|
113
|
-
def
|
|
114
|
-
"""Shared filter expandable
|
|
113
|
+
def shared_filter_sidebar(self):
|
|
114
|
+
"""Shared filter expandable sidebar."""
|
|
115
115
|
return self.sidebar_container.locator('a:has-text("shared")')
|
|
116
116
|
|
|
117
117
|
@property
|
|
@@ -187,14 +187,14 @@ class WorkflowSidebar:
|
|
|
187
187
|
def expand_project_filter(self):
|
|
188
188
|
"""Expand the project filter section."""
|
|
189
189
|
if not self.is_project_filter_expanded():
|
|
190
|
-
self.
|
|
190
|
+
self.project_filter_sidebar.click()
|
|
191
191
|
return self
|
|
192
192
|
|
|
193
193
|
@step
|
|
194
194
|
def collapse_project_filter(self):
|
|
195
195
|
"""Collapse the project filter section."""
|
|
196
196
|
if self.is_project_filter_expanded():
|
|
197
|
-
self.
|
|
197
|
+
self.project_filter_sidebar.click()
|
|
198
198
|
return self
|
|
199
199
|
|
|
200
200
|
@step
|
|
@@ -222,14 +222,14 @@ class WorkflowSidebar:
|
|
|
222
222
|
def expand_shared_filter(self):
|
|
223
223
|
"""Expand the shared filter section."""
|
|
224
224
|
if not self.is_shared_filter_expanded():
|
|
225
|
-
self.
|
|
225
|
+
self.shared_filter_sidebar.click()
|
|
226
226
|
return self
|
|
227
227
|
|
|
228
228
|
@step
|
|
229
229
|
def collapse_shared_filter(self):
|
|
230
230
|
"""Collapse the shared filter section."""
|
|
231
231
|
if self.is_shared_filter_expanded():
|
|
232
|
-
self.
|
|
232
|
+
self.shared_filter_sidebar.click()
|
|
233
233
|
return self
|
|
234
234
|
|
|
235
235
|
@step
|
|
@@ -342,27 +342,27 @@ class WorkflowSidebar:
|
|
|
342
342
|
@step
|
|
343
343
|
def should_have_filters_section(self):
|
|
344
344
|
"""Verify that the filters section is visible."""
|
|
345
|
-
expect(self.
|
|
345
|
+
expect(self.filters_sidebar).to_be_visible()
|
|
346
346
|
return self
|
|
347
347
|
|
|
348
348
|
@step
|
|
349
349
|
def should_have_project_filter_collapsed(self):
|
|
350
350
|
"""Verify that the project filter is collapsed."""
|
|
351
|
-
expect(self.
|
|
351
|
+
expect(self.project_filter_sidebar).to_be_visible()
|
|
352
352
|
expect(self.project_multiselect).not_to_be_visible()
|
|
353
353
|
return self
|
|
354
354
|
|
|
355
355
|
@step
|
|
356
356
|
def should_have_project_filter_expanded(self):
|
|
357
357
|
"""Verify that the project filter is expanded."""
|
|
358
|
-
expect(self.
|
|
358
|
+
expect(self.project_filter_sidebar).to_be_visible()
|
|
359
359
|
expect(self.project_multiselect).to_be_visible()
|
|
360
360
|
return self
|
|
361
361
|
|
|
362
362
|
@step
|
|
363
363
|
def should_have_shared_filter_collapsed(self):
|
|
364
364
|
"""Verify that the shared filter is collapsed."""
|
|
365
|
-
expect(self.
|
|
365
|
+
expect(self.shared_filter_sidebar).to_be_visible()
|
|
366
366
|
expect(self.with_project_radio_group).not_to_be_visible()
|
|
367
367
|
expect(self.not_shared_radio_group).not_to_be_visible()
|
|
368
368
|
return self
|
|
@@ -370,7 +370,7 @@ class WorkflowSidebar:
|
|
|
370
370
|
@step
|
|
371
371
|
def should_have_shared_filter_expanded(self):
|
|
372
372
|
"""Verify that the shared filter is expanded."""
|
|
373
|
-
expect(self.
|
|
373
|
+
expect(self.shared_filter_sidebar).to_be_visible()
|
|
374
374
|
expect(self.with_project_radio_group).to_be_visible()
|
|
375
375
|
expect(self.not_shared_radio_group).to_be_visible()
|
|
376
376
|
return self
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import platform
|
|
2
2
|
from playwright.sync_api import Page, Locator, expect
|
|
3
3
|
from reportportal_client import step
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
from codemie_test_harness.tests.ui.pageobject.base_page import BasePage
|
|
7
6
|
from codemie_test_harness.tests.ui.pageobject.components import WorkflowSidebar
|
|
7
|
+
from codemie_test_harness.tests.ui.pageobject.components import Menu
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class BaseWorkflowFormPage(BasePage):
|
|
@@ -13,6 +13,7 @@ class BaseWorkflowFormPage(BasePage):
|
|
|
13
13
|
def __init__(self, page: Page):
|
|
14
14
|
super().__init__(page)
|
|
15
15
|
self.sidebar = WorkflowSidebar(page)
|
|
16
|
+
self._menu = Menu(page)
|
|
16
17
|
|
|
17
18
|
# ==============================================
|
|
18
19
|
# PROPERTIES - UI ELEMENTS
|
|
@@ -60,56 +61,58 @@ class BaseWorkflowFormPage(BasePage):
|
|
|
60
61
|
@property
|
|
61
62
|
def shared_switch(self) -> Locator:
|
|
62
63
|
"""Shared with Project Team switch."""
|
|
63
|
-
return self.page.locator("
|
|
64
|
+
return self.page.locator("input#shared")
|
|
64
65
|
|
|
65
66
|
@property
|
|
66
67
|
def shared_switch_label(self) -> Locator:
|
|
67
68
|
"""Shared with Project Team switch label."""
|
|
68
|
-
return self.page.locator("
|
|
69
|
+
return self.page.locator("label#shared")
|
|
69
70
|
|
|
70
71
|
# ------ Name Field Elements ------
|
|
71
72
|
@property
|
|
72
73
|
def name_input(self) -> Locator:
|
|
73
74
|
"""Name input field."""
|
|
74
|
-
return self.page.locator("#name")
|
|
75
|
+
return self.page.locator("input#name")
|
|
75
76
|
|
|
76
77
|
@property
|
|
77
78
|
def name_field_label(self) -> Locator:
|
|
78
79
|
"""Name field label."""
|
|
79
|
-
return self.page.locator('
|
|
80
|
+
return self.page.locator('.input-label:has-text("Name")')
|
|
80
81
|
|
|
81
82
|
@property
|
|
82
83
|
def name_error_message(self):
|
|
83
84
|
"""Name field error message."""
|
|
84
|
-
return self.page.locator(
|
|
85
|
+
return self.page.locator(
|
|
86
|
+
"label.input-field-wrapper[for='name'] .input-error-message"
|
|
87
|
+
)
|
|
85
88
|
|
|
86
89
|
# ------ Description Field Elements ------
|
|
87
90
|
@property
|
|
88
91
|
def description_textarea(self) -> Locator:
|
|
89
92
|
"""Description textarea field."""
|
|
90
|
-
return self.page.locator("#description")
|
|
93
|
+
return self.page.locator("textarea#description")
|
|
91
94
|
|
|
92
95
|
@property
|
|
93
96
|
def description_field_label(self) -> Locator:
|
|
94
97
|
"""Description field label."""
|
|
95
|
-
return self.page.locator('
|
|
98
|
+
return self.page.locator('label[for="description"].textarea-label')
|
|
96
99
|
|
|
97
100
|
# ------ Icon URL Field Elements ------
|
|
98
101
|
@property
|
|
99
102
|
def icon_url_input(self) -> Locator:
|
|
100
103
|
"""Icon URL input field."""
|
|
101
|
-
return self.page.locator("#icon_url")
|
|
104
|
+
return self.page.locator("input#icon_url")
|
|
102
105
|
|
|
103
106
|
@property
|
|
104
107
|
def icon_url_field_label(self) -> Locator:
|
|
105
108
|
"""Icon URL field label."""
|
|
106
|
-
return self.page.locator('
|
|
109
|
+
return self.page.locator('.input-label:has-text("Icon URL")')
|
|
107
110
|
|
|
108
111
|
@property
|
|
109
112
|
def icon_url_error_message(self):
|
|
110
113
|
"""Icon URL field error message."""
|
|
111
114
|
return self.page.locator(
|
|
112
|
-
".input-field-wrapper
|
|
115
|
+
"label.input-field-wrapper[for='icon_url'] .input-error-message"
|
|
113
116
|
)
|
|
114
117
|
|
|
115
118
|
# ------ Workflow Mode Elements ------
|
|
@@ -118,11 +121,6 @@ class BaseWorkflowFormPage(BasePage):
|
|
|
118
121
|
"""Workflow Mode dropdown."""
|
|
119
122
|
return self.page.locator('.p-dropdown[data-pc-name="dropdown"]')
|
|
120
123
|
|
|
121
|
-
@property
|
|
122
|
-
def workflow_mode_label(self) -> Locator:
|
|
123
|
-
"""Workflow Mode field label."""
|
|
124
|
-
return self.page.locator('div.text-sm.font-semibold:has-text("Workflow Mode")')
|
|
125
|
-
|
|
126
124
|
@property
|
|
127
125
|
def workflow_mode_selected_value(self) -> Locator:
|
|
128
126
|
"""Currently selected workflow mode value."""
|
|
@@ -131,12 +129,12 @@ class BaseWorkflowFormPage(BasePage):
|
|
|
131
129
|
@property
|
|
132
130
|
def workflow_mode_info_icon(self) -> Locator:
|
|
133
131
|
"""Information icon next to workflow mode."""
|
|
134
|
-
return self.page.locator(".
|
|
132
|
+
return self.page.locator(".flex.w-full.px-2.gap-2 .opacity-75 svg")
|
|
135
133
|
|
|
136
134
|
@property
|
|
137
135
|
def workflow_mode_description(self) -> Locator:
|
|
138
136
|
"""Workflow mode description text."""
|
|
139
|
-
return self.page.locator(".flex.w-full.px-2.gap-2 .text-text-secondary.text-
|
|
137
|
+
return self.page.locator(".flex.w-full.px-2.gap-2 .text-text-secondary.text-xs")
|
|
140
138
|
|
|
141
139
|
# ------ YAML Configuration Elements ------
|
|
142
140
|
@property
|
|
@@ -175,49 +173,48 @@ class BaseWorkflowFormPage(BasePage):
|
|
|
175
173
|
@property
|
|
176
174
|
def visualize_button(self) -> Locator:
|
|
177
175
|
"""Visualize button."""
|
|
178
|
-
return self.page.locator('button.button.secondary.
|
|
176
|
+
return self.page.locator('button.button.secondary.medium:has-text("Visualize")')
|
|
179
177
|
|
|
180
178
|
@property
|
|
181
179
|
def visualization_placeholder(self) -> Locator:
|
|
182
180
|
"""Workflow visualization placeholder area."""
|
|
183
181
|
return self.page.locator(
|
|
184
|
-
"
|
|
182
|
+
".flex.flex-col.items-center.justify-center.bg-new-panel"
|
|
185
183
|
)
|
|
186
184
|
|
|
187
185
|
@property
|
|
188
186
|
def visualization_placeholder_text(self) -> Locator:
|
|
189
187
|
"""Visualization placeholder text."""
|
|
190
|
-
return self.
|
|
191
|
-
"//div[text()=' Workflow visualisation ']/../following-sibling::div/div[text()=' Workflow visualisation']"
|
|
192
|
-
)
|
|
188
|
+
return self.visualization_placeholder.locator(":scope > .text-md")
|
|
193
189
|
|
|
194
190
|
@property
|
|
195
191
|
def workflow_diagram(self) -> Locator:
|
|
196
|
-
"""Workflow diagram image."""
|
|
197
|
-
return self.
|
|
198
|
-
"//div[text()=' Workflow visualisation ']/../following-sibling::div//img[@alt='Workflow Diagram']"
|
|
199
|
-
)
|
|
192
|
+
"""Workflow diagram image (if/when present)."""
|
|
193
|
+
return self.visualization_placeholder.locator("img[alt='Workflow Diagram']")
|
|
200
194
|
|
|
201
195
|
@property
|
|
202
196
|
def reset_zooming(self) -> Locator:
|
|
203
197
|
"""Reset zooming button in visualization."""
|
|
204
|
-
return self.
|
|
205
|
-
"
|
|
198
|
+
return self.visualization_placeholder.locator(
|
|
199
|
+
"div.controll__buttons li.controll__home"
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
@property
|
|
203
|
+
def zoom_buttons(self) -> Locator:
|
|
204
|
+
"""Zoom buttons."""
|
|
205
|
+
return self.visualization_placeholder.locator(
|
|
206
|
+
"div.controll__buttons li.controll__zoom-in"
|
|
206
207
|
)
|
|
207
208
|
|
|
208
209
|
@property
|
|
209
210
|
def zoom_in_button(self) -> Locator:
|
|
210
211
|
"""Zoom in button in visualization."""
|
|
211
|
-
return self.
|
|
212
|
-
"//div[text()=' Workflow visualisation ']/../following-sibling::div/div/div/ul/li[3]"
|
|
213
|
-
)
|
|
212
|
+
return self.zoom_buttons.nth(0)
|
|
214
213
|
|
|
215
214
|
@property
|
|
216
215
|
def zoom_out_button(self) -> Locator:
|
|
217
216
|
"""Zoom out button in visualization."""
|
|
218
|
-
return self.
|
|
219
|
-
"//div[text()=' Workflow visualisation ']/../following-sibling::div/div/div/ul/li[4]"
|
|
220
|
-
)
|
|
217
|
+
return self.zoom_buttons.nth(1)
|
|
221
218
|
|
|
222
219
|
# ==============================================
|
|
223
220
|
# METHODS - ACTIONS & INTERACTIONS
|
|
@@ -275,14 +272,6 @@ class BaseWorkflowFormPage(BasePage):
|
|
|
275
272
|
"""Fill the icon URL field."""
|
|
276
273
|
self.icon_url_input.fill(icon_url)
|
|
277
274
|
|
|
278
|
-
# ------ Workflow Mode Actions ------
|
|
279
|
-
@step
|
|
280
|
-
def select_workflow_mode(self, mode: Optional[str] = None):
|
|
281
|
-
"""Select workflow mode from dropdown. If mode is None, just click to open."""
|
|
282
|
-
self.workflow_mode_dropdown.click()
|
|
283
|
-
if mode:
|
|
284
|
-
self.page.locator(f'li:has-text("{mode}")').click()
|
|
285
|
-
|
|
286
275
|
# ------ YAML Configuration Actions ------
|
|
287
276
|
@step
|
|
288
277
|
def fill_yaml_config(self, yaml_content: str):
|
|
@@ -366,27 +355,6 @@ class BaseWorkflowFormPage(BasePage):
|
|
|
366
355
|
"""Verify that the icon URL field is empty."""
|
|
367
356
|
expect(self.icon_url_input).to_have_value("")
|
|
368
357
|
|
|
369
|
-
# ------ Workflow Mode Verifications ------
|
|
370
|
-
@step
|
|
371
|
-
def should_have_workflow_mode_dropdown_visible(self):
|
|
372
|
-
"""Verify that the workflow mode dropdown is visible."""
|
|
373
|
-
expect(self.workflow_mode_dropdown).to_be_visible()
|
|
374
|
-
|
|
375
|
-
@step
|
|
376
|
-
def should_have_workflow_mode_selected(self, mode: str):
|
|
377
|
-
"""Verify that the specified workflow mode is selected."""
|
|
378
|
-
expect(self.workflow_mode_selected_value).to_have_text(mode)
|
|
379
|
-
|
|
380
|
-
@step
|
|
381
|
-
def should_show_workflow_mode_info(self):
|
|
382
|
-
"""Verify that workflow mode information is displayed."""
|
|
383
|
-
expect(self.workflow_mode_info_icon).to_be_visible()
|
|
384
|
-
expect(self.workflow_mode_description).to_be_visible()
|
|
385
|
-
expect(self.workflow_mode_description).to_contain_text(
|
|
386
|
-
"Sequential Mode offers full control. You define the workflow, choosing assistants and setting each step. "
|
|
387
|
-
"It's perfect for tasks needing specific, orderly execution. Opt for this when detail and sequence matter."
|
|
388
|
-
)
|
|
389
|
-
|
|
390
358
|
# ------ YAML Configuration Verifications ------
|
|
391
359
|
@step
|
|
392
360
|
def should_have_yaml_editor_visible(self):
|
|
@@ -445,7 +413,6 @@ class BaseWorkflowFormPage(BasePage):
|
|
|
445
413
|
expect(self.name_field_label).to_be_visible()
|
|
446
414
|
expect(self.description_field_label).to_be_visible()
|
|
447
415
|
expect(self.icon_url_field_label).to_be_visible()
|
|
448
|
-
expect(self.workflow_mode_label).to_be_visible()
|
|
449
416
|
expect(self.yaml_config_header).to_be_visible()
|
|
450
417
|
expect(self.visualization_header).to_be_visible()
|
|
451
418
|
return self
|
|
@@ -16,7 +16,7 @@ class CreateWorkflowPage(BaseWorkflowFormPage):
|
|
|
16
16
|
super().__init__(page)
|
|
17
17
|
|
|
18
18
|
# ==================== PROPERTIES ====================
|
|
19
|
-
#
|
|
19
|
+
# Menu elements specific to Create page
|
|
20
20
|
@property
|
|
21
21
|
def page_title(self):
|
|
22
22
|
"""Page title 'Create Workflow'."""
|
|
@@ -24,7 +24,7 @@ class CreateWorkflowPage(BaseWorkflowFormPage):
|
|
|
24
24
|
|
|
25
25
|
@property
|
|
26
26
|
def create_button(self):
|
|
27
|
-
"""Create button in the
|
|
27
|
+
"""Create button in the menu."""
|
|
28
28
|
return self.page.locator('button.button.primary.medium:has-text("Create")')
|
|
29
29
|
|
|
30
30
|
# ==================== NAVIGATION METHODS ====================
|
|
@@ -91,8 +91,8 @@ class CreateWorkflowPage(BaseWorkflowFormPage):
|
|
|
91
91
|
return self
|
|
92
92
|
|
|
93
93
|
@step
|
|
94
|
-
def
|
|
95
|
-
"""Verify that all
|
|
94
|
+
def should_have_menu_elements_visible(self):
|
|
95
|
+
"""Verify that all menu elements are visible."""
|
|
96
96
|
expect(self.back_button).to_be_visible()
|
|
97
97
|
expect(self.page_title).to_be_visible()
|
|
98
98
|
expect(self.cancel_button).to_be_visible()
|
|
@@ -27,7 +27,7 @@ class EditWorkflowPage(BaseWorkflowFormPage):
|
|
|
27
27
|
|
|
28
28
|
@property
|
|
29
29
|
def update_button(self) -> Locator:
|
|
30
|
-
"""Update button in the
|
|
30
|
+
"""Update button in the menu."""
|
|
31
31
|
return self.page.locator('button.button.primary.medium:has-text("Update")')
|
|
32
32
|
|
|
33
33
|
@property
|
|
@@ -68,7 +68,9 @@ class EditWorkflowPage(BaseWorkflowFormPage):
|
|
|
68
68
|
@property
|
|
69
69
|
def restore_button(self) -> Locator:
|
|
70
70
|
"""Restore button in history tab."""
|
|
71
|
-
return self.page.locator(
|
|
71
|
+
return self.page.locator(
|
|
72
|
+
'button.primary.medium.self-center:has-text("Restore")'
|
|
73
|
+
)
|
|
72
74
|
|
|
73
75
|
@property
|
|
74
76
|
def history_yaml_editor(self) -> Locator:
|
|
@@ -230,8 +232,8 @@ class EditWorkflowPage(BaseWorkflowFormPage):
|
|
|
230
232
|
expect(self.back_button).to_be_visible()
|
|
231
233
|
|
|
232
234
|
@step
|
|
233
|
-
def
|
|
234
|
-
"""Verify that all
|
|
235
|
+
def should_have_menu_elements_visible(self):
|
|
236
|
+
"""Verify that all menu elements are visible."""
|
|
235
237
|
expect(self.back_button).to_be_visible()
|
|
236
238
|
expect(self.page_title).to_be_visible()
|
|
237
239
|
expect(self.cancel_button).to_be_visible()
|