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
|
@@ -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):
|
|
@@ -22,13 +22,13 @@ class WorkflowExecutionsPage(BasePage):
|
|
|
22
22
|
@property
|
|
23
23
|
def workflow_title(self) -> Locator:
|
|
24
24
|
"""Workflow title in the header."""
|
|
25
|
-
return self.page.locator("div.text-
|
|
25
|
+
return self.page.locator("div.text-h3")
|
|
26
26
|
|
|
27
27
|
@property
|
|
28
28
|
def export_button(self) -> Locator:
|
|
29
29
|
"""Export button in the header."""
|
|
30
30
|
return self.page.locator(
|
|
31
|
-
'//button[text()=" Rerun workflow "]/preceding-sibling::button'
|
|
31
|
+
'//button[text()=" Rerun workflow "]/preceding-sibling::button[2]'
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
@property
|
|
@@ -41,7 +41,7 @@ class WorkflowExecutionsPage(BasePage):
|
|
|
41
41
|
@property
|
|
42
42
|
def sidebar(self) -> Locator:
|
|
43
43
|
"""Left sidebar container."""
|
|
44
|
-
return self.page.locator("aside.sidebar")
|
|
44
|
+
return self.page.locator("aside.w-workflow-exec-sidebar")
|
|
45
45
|
|
|
46
46
|
@property
|
|
47
47
|
def execution_history_title(self) -> Locator:
|
|
@@ -51,9 +51,7 @@ class WorkflowExecutionsPage(BasePage):
|
|
|
51
51
|
@property
|
|
52
52
|
def time_period_label(self) -> Locator:
|
|
53
53
|
"""Time period label (Last 7 days)."""
|
|
54
|
-
return self.page.locator(
|
|
55
|
-
'div.text-xs.text-text-secondary.uppercase:has-text("Last 7 days")'
|
|
56
|
-
)
|
|
54
|
+
return self.page.locator("div.text-xs.text-text-secondary.uppercase")
|
|
57
55
|
|
|
58
56
|
@property
|
|
59
57
|
def execution_history_items(self) -> Locator:
|
|
@@ -63,7 +61,9 @@ class WorkflowExecutionsPage(BasePage):
|
|
|
63
61
|
@property
|
|
64
62
|
def active_execution_item(self) -> Locator:
|
|
65
63
|
"""Currently active/selected execution item in sidebar."""
|
|
66
|
-
return self.page.locator(
|
|
64
|
+
return self.page.locator(
|
|
65
|
+
"div[class*='bg-new-stroke/60'][class*='!text-text-main']"
|
|
66
|
+
)
|
|
67
67
|
|
|
68
68
|
# ==================== MAIN CONTENT ELEMENTS ====================
|
|
69
69
|
|
|
@@ -107,12 +107,12 @@ class WorkflowExecutionsPage(BasePage):
|
|
|
107
107
|
@property
|
|
108
108
|
def prompt_section(self) -> Locator:
|
|
109
109
|
"""Prompt code block section."""
|
|
110
|
-
return self.page.locator("
|
|
110
|
+
return self.page.locator("pre.code-content.language-text")
|
|
111
111
|
|
|
112
112
|
@property
|
|
113
113
|
def prompt_code_block(self) -> Locator:
|
|
114
114
|
"""Prompt code block container."""
|
|
115
|
-
return self.
|
|
115
|
+
return self.page.locator("div.code-block.min-w-full")
|
|
116
116
|
|
|
117
117
|
@property
|
|
118
118
|
def prompt_header(self) -> Locator:
|
|
@@ -122,29 +122,27 @@ class WorkflowExecutionsPage(BasePage):
|
|
|
122
122
|
@property
|
|
123
123
|
def prompt_title(self) -> Locator:
|
|
124
124
|
"""Prompt title in header."""
|
|
125
|
-
return self.prompt_header.locator('div:has-text("
|
|
125
|
+
return self.prompt_header.locator('div:has-text("Prompt")')
|
|
126
126
|
|
|
127
127
|
@property
|
|
128
128
|
def prompt_info_button(self) -> Locator:
|
|
129
129
|
"""Prompt info button."""
|
|
130
|
-
return self.prompt_header.locator(
|
|
131
|
-
'xpath=.//button[text()=" Copy code "]/preceding-sibling::button'
|
|
132
|
-
)
|
|
130
|
+
return self.prompt_header.locator("button").first
|
|
133
131
|
|
|
134
132
|
@property
|
|
135
133
|
def prompt_copy_button(self) -> Locator:
|
|
136
134
|
"""Prompt copy code button."""
|
|
137
|
-
return self.prompt_header.locator(
|
|
135
|
+
return self.prompt_header.locator("button").nth(1)
|
|
138
136
|
|
|
139
137
|
@property
|
|
140
138
|
def prompt_download_button(self) -> Locator:
|
|
141
139
|
"""Prompt download button."""
|
|
142
|
-
return self.prompt_header.locator(
|
|
140
|
+
return self.prompt_header.locator("button").nth(2)
|
|
143
141
|
|
|
144
142
|
@property
|
|
145
143
|
def prompt_content(self) -> Locator:
|
|
146
144
|
"""Prompt code content."""
|
|
147
|
-
return self.prompt_code_block.locator("
|
|
145
|
+
return self.prompt_code_block.locator("code")
|
|
148
146
|
|
|
149
147
|
# ==================== STATES SECTION ====================
|
|
150
148
|
|
|
@@ -176,7 +174,7 @@ class WorkflowExecutionsPage(BasePage):
|
|
|
176
174
|
@property
|
|
177
175
|
def execution_states(self) -> Locator:
|
|
178
176
|
"""All execution state cards."""
|
|
179
|
-
return self.page.locator(
|
|
177
|
+
return self.page.locator(".flex.flex-col.justify-between.text-sm")
|
|
180
178
|
|
|
181
179
|
# ==================== PAGINATION SECTION ====================
|
|
182
180
|
|
|
@@ -448,8 +446,7 @@ class WorkflowExecutionsPage(BasePage):
|
|
|
448
446
|
self.should_have_status("Succeeded")
|
|
449
447
|
expect(self.status_badge).to_contain_class("bg-success-secondary")
|
|
450
448
|
expect(self.status_badge).to_contain_class("text-success-main")
|
|
451
|
-
expect(self.status_badge).to_contain_class("border-success-
|
|
452
|
-
expect(self.status_dot).to_contain_class("bg-success-main")
|
|
449
|
+
expect(self.status_badge).to_contain_class("border-success-border")
|
|
453
450
|
|
|
454
451
|
@step
|
|
455
452
|
def should_have_failed_status(self):
|
|
@@ -457,8 +454,7 @@ class WorkflowExecutionsPage(BasePage):
|
|
|
457
454
|
self.should_have_status("Failed")
|
|
458
455
|
expect(self.status_badge).to_contain_class("bg-error-secondary")
|
|
459
456
|
expect(self.status_badge).to_contain_class("text-error-main")
|
|
460
|
-
expect(self.status_badge).to_contain_class("border-error-
|
|
461
|
-
expect(self.status_dot).to_contain_class("bg-error-main")
|
|
457
|
+
expect(self.status_badge).to_contain_class("border-error-border")
|
|
462
458
|
|
|
463
459
|
@step
|
|
464
460
|
def should_have_triggered_by(self, expected_user: str):
|
|
@@ -522,13 +518,11 @@ class WorkflowExecutionsPage(BasePage):
|
|
|
522
518
|
@step
|
|
523
519
|
def should_have_configuration_sidebar_closed(self):
|
|
524
520
|
"""Verify that the configuration sidebar is closed."""
|
|
525
|
-
expect(self.configuration_sidebar).not_to_contain_class("w-[360px]")
|
|
526
521
|
expect(self.configuration_sidebar).not_to_contain_class("opacity-100")
|
|
527
522
|
|
|
528
523
|
@step
|
|
529
524
|
def should_have_configuration_sidebar_open(self):
|
|
530
525
|
"""Verify that the configuration sidebar is open."""
|
|
531
|
-
expect(self.configuration_sidebar).to_contain_class("w-[360px]")
|
|
532
526
|
expect(self.configuration_sidebar).to_contain_class("opacity-100")
|
|
533
527
|
expect(self.configure_workflow_title).to_be_visible()
|
|
534
528
|
expect(self.workflow_info_card).to_be_visible()
|
|
@@ -14,15 +14,10 @@ class WorkflowTemplateDetailsPage(BasePage):
|
|
|
14
14
|
super().__init__(page)
|
|
15
15
|
|
|
16
16
|
# ==================== PROPERTIES ====================
|
|
17
|
-
@property
|
|
18
|
-
def page_title(self):
|
|
19
|
-
return self.page.locator("div.text-lg")
|
|
20
17
|
|
|
21
18
|
@property
|
|
22
19
|
def create_workflow_button(self):
|
|
23
|
-
return self.page.locator(
|
|
24
|
-
"//button[@class='button base medium' and @type='button']"
|
|
25
|
-
)
|
|
20
|
+
return self.page.locator(".button.primary.medium")
|
|
26
21
|
|
|
27
22
|
@property
|
|
28
23
|
def back_button(self):
|
|
@@ -40,7 +35,7 @@ class WorkflowTemplateDetailsPage(BasePage):
|
|
|
40
35
|
|
|
41
36
|
@property
|
|
42
37
|
def copy_code_button(self):
|
|
43
|
-
return self.page.locator("//button[text()=' Copy
|
|
38
|
+
return self.page.locator("//button[text()=' Copy ']")
|
|
44
39
|
|
|
45
40
|
@property
|
|
46
41
|
def download_yaml_code_button(self):
|
|
@@ -64,11 +59,11 @@ class WorkflowTemplateDetailsPage(BasePage):
|
|
|
64
59
|
|
|
65
60
|
@property
|
|
66
61
|
def template_title(self):
|
|
67
|
-
return self.page.locator("
|
|
62
|
+
return self.page.locator("h4.text-2xl")
|
|
68
63
|
|
|
69
64
|
@property
|
|
70
65
|
def about_workflow(self):
|
|
71
|
-
return self.page.locator("div.text-
|
|
66
|
+
return self.page.locator("div.text-text-tertiary.break-words")
|
|
72
67
|
|
|
73
68
|
# ==================== INTERACTION METHODS ====================
|
|
74
69
|
@step
|
|
@@ -80,7 +75,6 @@ class WorkflowTemplateDetailsPage(BasePage):
|
|
|
80
75
|
@step
|
|
81
76
|
def should_have_template_header(self):
|
|
82
77
|
"""Verify workflow templates has given functionality."""
|
|
83
|
-
expect(self.page_title).to_have_text("Workflow Template Details")
|
|
84
78
|
expect(self.create_workflow_button).to_be_visible()
|
|
85
79
|
expect(self.create_workflow_button).to_be_enabled()
|
|
86
80
|
expect(self.back_button).to_be_visible()
|
|
@@ -91,7 +85,7 @@ class WorkflowTemplateDetailsPage(BasePage):
|
|
|
91
85
|
expect(self.template_title).to_have_text(template_title)
|
|
92
86
|
expect(self.about_workflow).to_have_text(description)
|
|
93
87
|
expect(self.template_icon).to_be_visible()
|
|
94
|
-
expect(self.yaml_config).
|
|
88
|
+
expect(self.yaml_config).to_be_visible()
|
|
95
89
|
expect(self.copy_code_button).to_be_visible()
|
|
96
90
|
expect(self.copy_code_button).to_be_enabled()
|
|
97
91
|
expect(self.download_yaml_code_button).to_be_visible()
|
|
@@ -20,7 +20,7 @@ class WorkflowTemplatesPage(BasePage):
|
|
|
20
20
|
|
|
21
21
|
@property
|
|
22
22
|
def templates_list(self):
|
|
23
|
-
return self.page.locator("
|
|
23
|
+
return self.page.locator(".body.h-card")
|
|
24
24
|
|
|
25
25
|
@property
|
|
26
26
|
def templates_create_list(self):
|
|
@@ -66,4 +66,7 @@ class WorkflowTemplatesPage(BasePage):
|
|
|
66
66
|
expect(workflow_card.title).to_have_text(title)
|
|
67
67
|
expect(workflow_card.description).to_contain_text(description)
|
|
68
68
|
workflow_page.hover_workflow_card(index)
|
|
69
|
-
|
|
69
|
+
if workflow_card.description_tooltip.is_visible():
|
|
70
|
+
expect(workflow_card.description_tooltip).to_contain_text(
|
|
71
|
+
tooltip_description
|
|
72
|
+
)
|
|
@@ -84,7 +84,7 @@ class WorkflowsPage(BasePage):
|
|
|
84
84
|
@property
|
|
85
85
|
def workflows_nav_link(self):
|
|
86
86
|
"""Main workflows navigation link."""
|
|
87
|
-
return self.page.locator('a[href="#/workflows/"]
|
|
87
|
+
return self.page.locator('a[href="#/workflows/"]')
|
|
88
88
|
|
|
89
89
|
@property
|
|
90
90
|
def loading_indicator(self):
|
|
@@ -228,15 +228,13 @@ class WorkflowsPage(BasePage):
|
|
|
228
228
|
def should_see_workflow_card(self, workflow_name: str):
|
|
229
229
|
"""Verify that a workflow card with the given name is visible."""
|
|
230
230
|
workflow_card = self.get_workflow_card_by_name(workflow_name)
|
|
231
|
-
workflow_card.
|
|
232
|
-
return self
|
|
231
|
+
return workflow_card.is_visible()
|
|
233
232
|
|
|
234
233
|
@step
|
|
235
234
|
def should_not_see_workflow_card(self, workflow_name: str):
|
|
236
235
|
"""Verify that a workflow card with the given name is not visible."""
|
|
237
236
|
workflow_card = self.get_workflow_card_by_name(workflow_name)
|
|
238
|
-
workflow_card.
|
|
239
|
-
return self
|
|
237
|
+
return not workflow_card.is_visible()
|
|
240
238
|
|
|
241
239
|
@step
|
|
242
240
|
def should_see_workflow_with_title(self, workflow_name: str, expected_title: str):
|
|
File without changes
|
|
@@ -22,14 +22,14 @@ def test_create_workflow_page_elements_visibility(page):
|
|
|
22
22
|
# Verify we are on the correct page
|
|
23
23
|
create_page.should_be_on_create_workflow_page(expected_create_workflow_title)
|
|
24
24
|
|
|
25
|
-
# Verify
|
|
26
|
-
create_page.
|
|
25
|
+
# Verify menu elements
|
|
26
|
+
create_page.should_have_menu_elements_visible()
|
|
27
27
|
|
|
28
28
|
# Verify all form sections are visible
|
|
29
29
|
create_page.should_have_all_form_sections_visible()
|
|
30
30
|
|
|
31
31
|
# Verify common components
|
|
32
|
-
create_page.
|
|
32
|
+
create_page.should_have_menu_visible()
|
|
33
33
|
create_page.sidebar.should_be_visible()
|
|
34
34
|
create_page.sidebar.should_have_workflows_title()
|
|
35
35
|
|
|
@@ -68,7 +68,7 @@ def test_create_workflow_form_interactions(page):
|
|
|
68
68
|
@pytest.mark.workflow_ui
|
|
69
69
|
@pytest.mark.ui
|
|
70
70
|
def test_create_workflow_dropdowns_interaction(page):
|
|
71
|
-
"""Test dropdown interactions for project
|
|
71
|
+
"""Test dropdown interactions for project."""
|
|
72
72
|
create_page = CreateWorkflowPage(page)
|
|
73
73
|
create_page.navigate_to()
|
|
74
74
|
|
|
@@ -79,13 +79,6 @@ def test_create_workflow_dropdowns_interaction(page):
|
|
|
79
79
|
create_page.search_and_select_project(os.getenv("PROJECT_NAME"))
|
|
80
80
|
create_page.should_see_project_selected(os.getenv("PROJECT_NAME"))
|
|
81
81
|
|
|
82
|
-
create_page.should_have_workflow_mode_dropdown_visible()
|
|
83
|
-
create_page.select_workflow_mode() # Just opens dropdown
|
|
84
|
-
create_page.page_title.click()
|
|
85
|
-
|
|
86
|
-
# Verify the default selection is maintained
|
|
87
|
-
create_page.should_have_workflow_mode_selected("Sequential")
|
|
88
|
-
|
|
89
82
|
|
|
90
83
|
@pytest.mark.workflow_ui
|
|
91
84
|
@pytest.mark.ui
|
|
@@ -173,37 +166,26 @@ def test_create_workflow_sidebar_functionality(page):
|
|
|
173
166
|
|
|
174
167
|
@pytest.mark.workflow_ui
|
|
175
168
|
@pytest.mark.ui
|
|
176
|
-
def
|
|
177
|
-
"""Test
|
|
169
|
+
def test_create_workflow_menu_navigation(page):
|
|
170
|
+
"""Test menu navigation from Create Workflow page."""
|
|
178
171
|
create_page = CreateWorkflowPage(page)
|
|
179
172
|
create_page.navigate_to()
|
|
180
173
|
|
|
181
|
-
# Test
|
|
182
|
-
create_page.
|
|
183
|
-
create_page.
|
|
184
|
-
create_page.
|
|
174
|
+
# Test menu component visibility
|
|
175
|
+
create_page.should_have_menu_visible()
|
|
176
|
+
create_page.menu.should_be_visible()
|
|
177
|
+
create_page.menu.should_have_complete_navigation_structure()
|
|
185
178
|
|
|
186
179
|
# Test navigation to other sections
|
|
187
|
-
create_page.
|
|
180
|
+
create_page.menu.navigate_to_assistants()
|
|
188
181
|
create_page.should_have_url_containing("#/assistants")
|
|
189
182
|
|
|
190
183
|
# Navigate back to create workflow
|
|
191
184
|
create_page.navigate_to()
|
|
192
|
-
create_page.
|
|
185
|
+
create_page.menu.navigate_to_workflows()
|
|
193
186
|
create_page.should_have_url_containing("#/workflows")
|
|
194
187
|
|
|
195
188
|
|
|
196
|
-
@pytest.mark.workflow_ui
|
|
197
|
-
@pytest.mark.ui
|
|
198
|
-
def test_create_workflow_workflow_mode_information(page):
|
|
199
|
-
"""Test workflow mode information display."""
|
|
200
|
-
create_page = CreateWorkflowPage(page)
|
|
201
|
-
create_page.navigate_to()
|
|
202
|
-
|
|
203
|
-
# Test workflow mode information display
|
|
204
|
-
create_page.should_show_workflow_mode_info()
|
|
205
|
-
|
|
206
|
-
|
|
207
189
|
@pytest.mark.workflow_ui
|
|
208
190
|
@pytest.mark.ui
|
|
209
191
|
def test_create_workflow_default_field_values(page):
|
|
@@ -219,9 +201,6 @@ def test_create_workflow_default_field_values(page):
|
|
|
219
201
|
# Test default shared switch state
|
|
220
202
|
create_page.should_have_shared_switch_unchecked()
|
|
221
203
|
|
|
222
|
-
# Test default workflow mode selection
|
|
223
|
-
create_page.should_have_workflow_mode_selected("Sequential")
|
|
224
|
-
|
|
225
204
|
|
|
226
205
|
@pytest.mark.workflow_ui
|
|
227
206
|
@pytest.mark.ui
|
|
@@ -60,14 +60,14 @@ def test_edit_workflow_page_elements_visibility(page, test_workflow):
|
|
|
60
60
|
# Verify we are on the correct page
|
|
61
61
|
edit_page.should_be_on_edit_workflow_page()
|
|
62
62
|
|
|
63
|
-
# Verify
|
|
64
|
-
edit_page.
|
|
63
|
+
# Verify menu elements
|
|
64
|
+
edit_page.should_have_menu_elements_visible()
|
|
65
65
|
|
|
66
66
|
# Verify all form sections are visible
|
|
67
67
|
edit_page.should_have_all_form_sections_visible()
|
|
68
68
|
|
|
69
69
|
# Verify common components
|
|
70
|
-
edit_page.
|
|
70
|
+
edit_page.menu.should_have_complete_navigation_structure()
|
|
71
71
|
edit_page.sidebar.should_be_visible()
|
|
72
72
|
edit_page.sidebar.should_have_workflows_title()
|
|
73
73
|
|
|
@@ -83,7 +83,6 @@ def test_edit_workflow_form_pre_populated_data(page, test_workflow):
|
|
|
83
83
|
edit_page.should_have_project_selected(test_workflow.project)
|
|
84
84
|
edit_page.should_have_name_field_value(test_workflow.name)
|
|
85
85
|
edit_page.should_have_description_field_value(test_workflow.description)
|
|
86
|
-
edit_page.should_have_workflow_mode_selected("Sequential")
|
|
87
86
|
edit_page.should_have_shared_switch_checked()
|
|
88
87
|
|
|
89
88
|
# Verify YAML editor has content
|
|
@@ -125,7 +124,7 @@ def test_edit_workflow_form_interactions(page, test_workflow):
|
|
|
125
124
|
@pytest.mark.workflow_ui
|
|
126
125
|
@pytest.mark.ui
|
|
127
126
|
def test_edit_workflow_dropdowns_interaction(page, test_workflow):
|
|
128
|
-
"""Test dropdown interactions for project
|
|
127
|
+
"""Test dropdown interactions for project."""
|
|
129
128
|
edit_page = EditWorkflowPage(page)
|
|
130
129
|
edit_page.navigate_to(test_workflow.id)
|
|
131
130
|
|
|
@@ -136,14 +135,6 @@ def test_edit_workflow_dropdowns_interaction(page, test_workflow):
|
|
|
136
135
|
edit_page.search_and_select_project(os.getenv("PROJECT_NAME"))
|
|
137
136
|
edit_page.should_see_project_selected(os.getenv("PROJECT_NAME"))
|
|
138
137
|
|
|
139
|
-
# Test workflow mode dropdown interaction
|
|
140
|
-
edit_page.select_workflow_mode() # Just opens dropdown
|
|
141
|
-
# Close dropdown by clicking elsewhere
|
|
142
|
-
edit_page.page_title.click()
|
|
143
|
-
|
|
144
|
-
# Verify the default selection is maintained
|
|
145
|
-
edit_page.should_have_workflow_mode_selected("Sequential")
|
|
146
|
-
|
|
147
138
|
|
|
148
139
|
@pytest.mark.workflow_ui
|
|
149
140
|
@pytest.mark.ui
|
|
@@ -203,6 +194,7 @@ def test_edit_workflow_visualization_section(page, test_workflow):
|
|
|
203
194
|
edit_page.should_have_workflow_diagram_visible()
|
|
204
195
|
|
|
205
196
|
|
|
197
|
+
@pytest.mark.skip(reason="Need to rewrite whole case")
|
|
206
198
|
@pytest.mark.workflow_ui
|
|
207
199
|
@pytest.mark.ui
|
|
208
200
|
def test_edit_workflow_navigation_buttons(page, test_workflow):
|
|
@@ -245,37 +237,26 @@ def test_edit_workflow_sidebar_functionality(page, test_workflow):
|
|
|
245
237
|
|
|
246
238
|
@pytest.mark.workflow_ui
|
|
247
239
|
@pytest.mark.ui
|
|
248
|
-
def
|
|
249
|
-
"""Test
|
|
240
|
+
def test_edit_workflow_menu_navigation(page, test_workflow):
|
|
241
|
+
"""Test menu navigation from Edit Workflow page."""
|
|
250
242
|
edit_page = EditWorkflowPage(page)
|
|
251
243
|
edit_page.navigate_to(test_workflow.id)
|
|
252
244
|
|
|
253
|
-
# Test
|
|
254
|
-
edit_page.
|
|
255
|
-
edit_page.
|
|
256
|
-
edit_page.
|
|
245
|
+
# Test menu component visibility
|
|
246
|
+
edit_page.should_have_menu_visible()
|
|
247
|
+
edit_page.menu.should_be_visible()
|
|
248
|
+
edit_page.menu.should_have_complete_navigation_structure()
|
|
257
249
|
|
|
258
250
|
# Test navigation to other sections
|
|
259
|
-
edit_page.
|
|
251
|
+
edit_page.menu.navigate_to_assistants()
|
|
260
252
|
edit_page.should_have_url_containing("#/assistants")
|
|
261
253
|
|
|
262
254
|
# Navigate back to edit workflow
|
|
263
255
|
edit_page.navigate_to(test_workflow.id)
|
|
264
|
-
edit_page.
|
|
256
|
+
edit_page.menu.navigate_to_workflows()
|
|
265
257
|
edit_page.should_have_url_containing("#/workflows/my")
|
|
266
258
|
|
|
267
259
|
|
|
268
|
-
@pytest.mark.workflow_ui
|
|
269
|
-
@pytest.mark.ui
|
|
270
|
-
def test_edit_workflow_workflow_mode_information(page, test_workflow):
|
|
271
|
-
"""Test workflow mode information display."""
|
|
272
|
-
edit_page = EditWorkflowPage(page)
|
|
273
|
-
edit_page.navigate_to(test_workflow.id)
|
|
274
|
-
|
|
275
|
-
# Test workflow mode information display
|
|
276
|
-
edit_page.should_show_workflow_mode_info()
|
|
277
|
-
|
|
278
|
-
|
|
279
260
|
@pytest.mark.workflow_ui
|
|
280
261
|
@pytest.mark.ui
|
|
281
262
|
def test_edit_workflow_data_persistence_across_tabs(page, test_workflow):
|
|
@@ -353,13 +334,12 @@ def test_edit_workflow_complete_update(page, test_workflow):
|
|
|
353
334
|
)
|
|
354
335
|
|
|
355
336
|
workflows_page = WorkflowsPage(page)
|
|
356
|
-
workflows_page.
|
|
337
|
+
workflows_page.navigate_to()
|
|
357
338
|
workflows_page.should_see_workflow_card(test_workflow.name)
|
|
358
339
|
|
|
359
340
|
edit_page.navigate_to(test_workflow.id)
|
|
360
341
|
edit_page.should_have_name_field_value(test_workflow.name)
|
|
361
342
|
edit_page.should_have_description_field_value(test_workflow.description)
|
|
362
|
-
edit_page.should_have_workflow_mode_selected("Sequential")
|
|
363
343
|
edit_page.should_have_shared_switch_unchecked()
|
|
364
344
|
edit_page.should_have_yaml_editor_with_content(test_workflow.yaml_config)
|
|
365
345
|
|