codemie-test-harness 0.1.167__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/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.167.dist-info → codemie_test_harness-0.1.168.dist-info}/METADATA +2 -2
- {codemie_test_harness-0.1.167.dist-info → codemie_test_harness-0.1.168.dist-info}/RECORD +28 -27
- {codemie_test_harness-0.1.167.dist-info → codemie_test_harness-0.1.168.dist-info}/WHEEL +0 -0
- {codemie_test_harness-0.1.167.dist-info → codemie_test_harness-0.1.168.dist-info}/entry_points.txt +0 -0
|
@@ -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()
|
|
@@ -28,9 +28,7 @@ class WorkflowDetailsPage(BasePage):
|
|
|
28
28
|
@property
|
|
29
29
|
def page_title(self) -> Locator:
|
|
30
30
|
"""Page title 'Workflow Details'."""
|
|
31
|
-
return self.page.locator(
|
|
32
|
-
'div.text-lg.font-semibold:has-text("Workflow Details")'
|
|
33
|
-
)
|
|
31
|
+
return self.page.locator('div.text-h3:has-text("Workflow Details")')
|
|
34
32
|
|
|
35
33
|
@property
|
|
36
34
|
def workflow_avatar(self) -> Locator:
|
|
@@ -40,7 +38,7 @@ class WorkflowDetailsPage(BasePage):
|
|
|
40
38
|
@property
|
|
41
39
|
def workflow_name(self) -> Locator:
|
|
42
40
|
"""Workflow name heading."""
|
|
43
|
-
return self.page.locator(
|
|
41
|
+
return self.page.locator("h4.text-2xl ")
|
|
44
42
|
|
|
45
43
|
@property
|
|
46
44
|
def workflow_author(self) -> Locator:
|
|
@@ -62,9 +60,7 @@ class WorkflowDetailsPage(BasePage):
|
|
|
62
60
|
@property
|
|
63
61
|
def run_workflow_button(self) -> Locator:
|
|
64
62
|
"""Run workflow button."""
|
|
65
|
-
return self.page.locator(
|
|
66
|
-
'button.button.primary.medium:has-text("Run workflow")'
|
|
67
|
-
)
|
|
63
|
+
return self.page.locator('.button.primary.medium:has-text("Run workflow")')
|
|
68
64
|
|
|
69
65
|
# Tab Elements
|
|
70
66
|
@property
|
|
@@ -170,12 +166,9 @@ class WorkflowDetailsPage(BasePage):
|
|
|
170
166
|
@property
|
|
171
167
|
def about_workflow_section(self) -> Locator:
|
|
172
168
|
"""About workflow section."""
|
|
173
|
-
return self.page.locator(
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
def workflow_description(self) -> Locator:
|
|
177
|
-
"""Workflow description text."""
|
|
178
|
-
return self.page.locator("div.text-sm.text-text-tertiary").first
|
|
169
|
+
return self.page.locator(
|
|
170
|
+
'//div[contains(text(),"About workflow:")]/following::div'
|
|
171
|
+
).first
|
|
179
172
|
|
|
180
173
|
@property
|
|
181
174
|
def workflow_graph_schema_section(self) -> Locator:
|
|
@@ -190,7 +183,7 @@ class WorkflowDetailsPage(BasePage):
|
|
|
190
183
|
@property
|
|
191
184
|
def config_code_block(self) -> Locator:
|
|
192
185
|
"""Configuration code block container."""
|
|
193
|
-
return self.page.locator("div.
|
|
186
|
+
return self.page.locator("div.code-block > pre.code-content")
|
|
194
187
|
|
|
195
188
|
@property
|
|
196
189
|
def code_block_header(self) -> Locator:
|
|
@@ -205,12 +198,12 @@ class WorkflowDetailsPage(BasePage):
|
|
|
205
198
|
@property
|
|
206
199
|
def copy_code_button(self) -> Locator:
|
|
207
200
|
"""Copy code button."""
|
|
208
|
-
return self.page.locator('button
|
|
201
|
+
return self.page.locator('//button[normalize-space()="Copy"]')
|
|
209
202
|
|
|
210
203
|
@property
|
|
211
204
|
def download_code_button(self) -> Locator:
|
|
212
205
|
"""Download button."""
|
|
213
|
-
return self.page.locator('button
|
|
206
|
+
return self.page.locator('//button[normalize-space()="Download"]')
|
|
214
207
|
|
|
215
208
|
@property
|
|
216
209
|
def code_content(self) -> Locator:
|
|
@@ -228,11 +221,6 @@ class WorkflowDetailsPage(BasePage):
|
|
|
228
221
|
"""Overview title in sidebar."""
|
|
229
222
|
return self.page.locator('span:has-text("OVERVIEW")').first
|
|
230
223
|
|
|
231
|
-
@property
|
|
232
|
-
def mode_info(self) -> Locator:
|
|
233
|
-
"""Mode information in sidebar."""
|
|
234
|
-
return self.page.locator('div:has-text("Mode:")').first
|
|
235
|
-
|
|
236
224
|
@property
|
|
237
225
|
def project_info(self) -> Locator:
|
|
238
226
|
"""Project information in sidebar."""
|
|
@@ -240,15 +228,13 @@ class WorkflowDetailsPage(BasePage):
|
|
|
240
228
|
|
|
241
229
|
@property
|
|
242
230
|
def workflow_id_section(self) -> Locator:
|
|
243
|
-
"""Workflow ID
|
|
244
|
-
return self.page.locator(
|
|
245
|
-
'//div[text()="Workflow ID"]/following-sibling::label/div'
|
|
246
|
-
)
|
|
231
|
+
"""Workflow ID tab in Overview."""
|
|
232
|
+
return self.page.locator('//div[.="Workflow ID"]/following-sibling::label')
|
|
247
233
|
|
|
248
234
|
@property
|
|
249
235
|
def workflow_id_input(self) -> Locator:
|
|
250
236
|
"""Workflow ID input field."""
|
|
251
|
-
return self.workflow_id_section.locator("//input[@
|
|
237
|
+
return self.workflow_id_section.locator("//input[@readonly]")
|
|
252
238
|
|
|
253
239
|
@property
|
|
254
240
|
def workflow_id_copy_button(self) -> Locator:
|
|
@@ -256,28 +242,21 @@ class WorkflowDetailsPage(BasePage):
|
|
|
256
242
|
return self.workflow_id_section.locator("//button")
|
|
257
243
|
|
|
258
244
|
@property
|
|
259
|
-
def
|
|
260
|
-
"""Access Links
|
|
261
|
-
return self.page.locator(
|
|
262
|
-
'//div[text()=" Access Links "]/following-sibling::label/div'
|
|
263
|
-
)
|
|
245
|
+
def workflow_access_links_section(self) -> Locator:
|
|
246
|
+
"""Workflow Access Links tab in Overview."""
|
|
247
|
+
return self.page.locator('//div[.="Access Links"]/following-sibling::label')
|
|
264
248
|
|
|
265
249
|
@property
|
|
266
|
-
def
|
|
267
|
-
"""
|
|
268
|
-
return self.
|
|
269
|
-
'../preceding-sibling::div[text()="Link to workflow details:"]'
|
|
270
|
-
)
|
|
250
|
+
def workflow_access_links_input(self) -> Locator:
|
|
251
|
+
"""Workflow Access Links input field."""
|
|
252
|
+
return self.workflow_access_links_section.locator("//input[@readonly]")
|
|
271
253
|
|
|
272
254
|
@property
|
|
273
|
-
def
|
|
274
|
-
"""
|
|
275
|
-
return self.
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
def workflow_details_link_copy_button(self) -> Locator:
|
|
279
|
-
"""Copy button for workflow details link."""
|
|
280
|
-
return self.access_links_section.locator("//button")
|
|
255
|
+
def workflow_access_links_copy_button(self) -> Locator:
|
|
256
|
+
"""Copy button for workflow Access Links."""
|
|
257
|
+
return self.workflow_access_links_section.locator(
|
|
258
|
+
"//div[contains(@class, 'input-right-icon')]//button"
|
|
259
|
+
)
|
|
281
260
|
|
|
282
261
|
# ==================== NAVIGATION METHODS ====================
|
|
283
262
|
|
|
@@ -540,7 +519,7 @@ class WorkflowDetailsPage(BasePage):
|
|
|
540
519
|
"""Verify that the Export popup is visible with expected content."""
|
|
541
520
|
expect(self.pop_up.cancel).to_have_text("Cancel")
|
|
542
521
|
expect(self.pop_up.submit).to_have_text("Export")
|
|
543
|
-
expect(self.pop_up.
|
|
522
|
+
expect(self.pop_up.menu).to_have_text("Export Workflow Execution")
|
|
544
523
|
expect(self.pop_up.close).to_be_visible()
|
|
545
524
|
|
|
546
525
|
@step
|
|
@@ -554,7 +533,6 @@ class WorkflowDetailsPage(BasePage):
|
|
|
554
533
|
def should_have_configuration_elements_visible(self):
|
|
555
534
|
"""Verify that all configuration tab elements are visible."""
|
|
556
535
|
expect(self.about_workflow_section).to_be_visible()
|
|
557
|
-
expect(self.workflow_description).to_be_visible()
|
|
558
536
|
expect(self.workflow_graph_schema_section).to_be_visible()
|
|
559
537
|
expect(self.workflow_graph_image).to_be_visible()
|
|
560
538
|
expect(self.config_code_block).to_be_visible()
|
|
@@ -574,33 +552,26 @@ class WorkflowDetailsPage(BasePage):
|
|
|
574
552
|
"""Verify that overview sidebar is visible with all elements."""
|
|
575
553
|
expect(self.overview_sidebar).to_be_visible()
|
|
576
554
|
expect(self.overview_title).to_be_visible()
|
|
577
|
-
expect(self.mode_info).to_be_visible()
|
|
578
555
|
expect(self.project_info).to_be_visible()
|
|
579
556
|
|
|
580
557
|
@step
|
|
581
558
|
def should_have_workflow_id_section_visible(self):
|
|
582
559
|
"""Verify that workflow ID section is visible."""
|
|
583
560
|
expect(self.workflow_id_section).to_be_visible()
|
|
561
|
+
expect(self.workflow_id_copy_button).to_be_visible()
|
|
584
562
|
expect(self.workflow_id_input).to_be_visible()
|
|
585
|
-
expect(self.workflow_id_input).to_be_disabled()
|
|
586
563
|
|
|
587
564
|
@step
|
|
588
565
|
def should_have_access_links_section_visible(self):
|
|
589
566
|
"""Verify that access links section is visible."""
|
|
590
|
-
expect(self.
|
|
591
|
-
expect(self.
|
|
592
|
-
expect(self.
|
|
593
|
-
expect(self.workflow_details_link_input).to_be_disabled()
|
|
567
|
+
expect(self.workflow_access_links_section).to_be_visible()
|
|
568
|
+
expect(self.workflow_access_links_copy_button).to_be_visible()
|
|
569
|
+
expect(self.workflow_access_links_input).to_be_visible()
|
|
594
570
|
|
|
595
571
|
@step
|
|
596
572
|
def should_have_workflow_description(self, expected_description: str):
|
|
597
573
|
"""Verify the workflow description text."""
|
|
598
|
-
expect(self.
|
|
599
|
-
|
|
600
|
-
@step
|
|
601
|
-
def should_have_mode_value(self, expected_mode: str):
|
|
602
|
-
"""Verify the mode value in overview."""
|
|
603
|
-
expect(self.mode_info).to_contain_text(expected_mode)
|
|
574
|
+
expect(self.about_workflow_section).to_have_text(expected_description)
|
|
604
575
|
|
|
605
576
|
@step
|
|
606
577
|
def should_have_project_value(self, expected_project: str):
|
|
@@ -615,8 +586,8 @@ class WorkflowDetailsPage(BasePage):
|
|
|
615
586
|
@step
|
|
616
587
|
def should_have_workflow_details_link_value(self, workflow_id: str):
|
|
617
588
|
"""Verify the workflow details link value."""
|
|
618
|
-
expect(self.
|
|
619
|
-
f"{os.getenv('
|
|
589
|
+
expect(self.workflow_access_links_input).to_have_value(
|
|
590
|
+
f"{os.getenv('FRONTEND_URL')}#/workflows?workflow={workflow_id}"
|
|
620
591
|
)
|
|
621
592
|
|
|
622
593
|
@step
|
|
@@ -648,7 +619,7 @@ class WorkflowDetailsPage(BasePage):
|
|
|
648
619
|
@step
|
|
649
620
|
def click_copy_workflow_details_link(self):
|
|
650
621
|
"""Click the copy workflow details link button."""
|
|
651
|
-
self.
|
|
622
|
+
self.workflow_access_links_copy_button.click()
|
|
652
623
|
|
|
653
624
|
@step
|
|
654
625
|
def should_have_graph_image_loaded(self):
|