Skip to content

Commit 2f12ae9

Browse files
authored
Merge pull request #21058 from jmchilton/selenium_20912
Selenium test exercising workflow debug, failed jobs, etc... (20912)
2 parents f354649 + 94dcb86 commit 2f12ae9

File tree

5 files changed

+128
-54
lines changed

5 files changed

+128
-54
lines changed

client/src/components/WorkflowInvocationState/InvocationStepStateDisplay.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ const props = defineProps<{
1111
</script>
1212

1313
<template>
14-
<span class="d-flex align-items-center">
14+
<span
15+
class="d-flex align-items-center"
16+
data-description="invocation step state counter"
17+
:data-state="state"
18+
:data-count="jobCount">
1519
<FontAwesomeIcon
1620
v-if="iconClasses[props.state]"
1721
:icon="iconClasses[props.state]?.icon"

client/src/utils/navigation/navigation.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,7 @@ invocations:
10411041
selector: '//span[contains(@class, "content-title name")][text()="${element_identifier}"]'
10421042
step_output_collection_element_datatype: '[data-step="${order_index}"] .invocation-step-output-collection-details .not-loading .datatype .value'
10431043
step_job_details: '[data-step="${order_index}"] .invocation-step-job-details'
1044+
step_job_details_state_counter: '[data-description="invocation step state counter"][data-state="${state}"]'
10441045
step_job_information: '[data-step="${order_index}"] .invocation-step-job-details .info_data_table'
10451046
step_job_information_tool_id: '[data-step="${order_index}"] .invocation-step-job-details .info_data_table #galaxy-tool-id'
10461047
export_tab: '.invocation-export-tab'

lib/galaxy_test/api/test_workflows.py

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
NESTED_WORKFLOW_WITH_CONDITIONAL_SUBWORKFLOW_AND_DISCONNECTED_MAP_OVER_SOURCE,
4242
WORKFLOW_FLAT_CROSS_PRODUCT,
4343
WORKFLOW_INPUTS_AS_OUTPUTS,
44+
WORKFLOW_KEEP_SUCCESSFUL_DATASETS,
45+
WORKFLOW_KEEP_SUCCESSFUL_DATASETS_TEST_DATA,
4446
WORKFLOW_LIST_PAIRED_INPUT_TO_TYPE_SOURCE,
4547
WORKFLOW_NESTED_REPLACEMENT_PARAMETER,
4648
WORKFLOW_NESTED_RUNTIME_PARAMETER,
@@ -3790,36 +3792,8 @@ def filter_jobs_by_tool(tool_id):
37903792
def test_keep_success_mapping_error(self):
37913793
with self.dataset_populator.test_history() as history_id:
37923794
summary = self._run_workflow(
3793-
"""
3794-
class: GalaxyWorkflow
3795-
inputs:
3796-
input_c: collection
3797-
3798-
steps:
3799-
mixed_collection:
3800-
tool_id: exit_code_from_file
3801-
in:
3802-
input: input_c
3803-
3804-
filtered_collection:
3805-
tool_id: "__KEEP_SUCCESS_DATASETS__"
3806-
in:
3807-
input: mixed_collection/out_file1
3808-
3809-
cat:
3810-
tool_id: cat1
3811-
in:
3812-
input1: filtered_collection/output
3813-
""",
3814-
test_data="""
3815-
input_c:
3816-
collection_type: list
3817-
elements:
3818-
- identifier: i1
3819-
content: "0"
3820-
- identifier: i2
3821-
content: "1"
3822-
""",
3795+
WORKFLOW_KEEP_SUCCESSFUL_DATASETS,
3796+
test_data=WORKFLOW_KEEP_SUCCESSFUL_DATASETS_TEST_DATA,
38233797
history_id=history_id,
38243798
wait=True,
38253799
assert_ok=False,

lib/galaxy_test/base/workflow_fixtures.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,3 +1280,35 @@
12801280
"uuid": "03a95ebe-af1e-4628-ac2f-e7553babfb2f",
12811281
"version": 3
12821282
}"""
1283+
1284+
WORKFLOW_KEEP_SUCCESSFUL_DATASETS = """
1285+
class: GalaxyWorkflow
1286+
inputs:
1287+
input_c: collection
1288+
1289+
steps:
1290+
mixed_collection:
1291+
tool_id: exit_code_from_file
1292+
in:
1293+
input: input_c
1294+
1295+
filtered_collection:
1296+
tool_id: "__KEEP_SUCCESS_DATASETS__"
1297+
in:
1298+
input: mixed_collection/out_file1
1299+
1300+
cat:
1301+
tool_id: cat
1302+
in:
1303+
input1: filtered_collection/output
1304+
"""
1305+
1306+
WORKFLOW_KEEP_SUCCESSFUL_DATASETS_TEST_DATA = """
1307+
input_c:
1308+
collection_type: list
1309+
elements:
1310+
- identifier: i1
1311+
content: "0"
1312+
- identifier: i2
1313+
content: "1"
1314+
"""

lib/galaxy_test/selenium/test_workflow_invocation_details.py

Lines changed: 86 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
from galaxy_test.base.workflow_fixtures import WORKFLOW_WITH_OUTPUT_COLLECTION
1+
from galaxy_test.base.workflow_fixtures import (
2+
WORKFLOW_KEEP_SUCCESSFUL_DATASETS,
3+
WORKFLOW_KEEP_SUCCESSFUL_DATASETS_TEST_DATA,
4+
WORKFLOW_WITH_OUTPUT_COLLECTION,
5+
)
26
from .framework import (
7+
managed_history,
38
retry_assertion_during_transitions,
49
selenium_test,
510
SeleniumTestCase,
@@ -17,29 +22,9 @@ def test_job_details(self):
1722
WORKFLOW_WITH_OUTPUT_COLLECTION, history_id=history_id, assert_ok=True, wait=True
1823
)
1924

20-
# open invocations panel
21-
self.home()
22-
gx_selenium_context.components.invocations.activity.wait_for_and_click()
23-
24-
invocations = gx_selenium_context.components.invocations
25-
invocations.invocations_panel_list.wait_for_visible()
26-
27-
@retry_assertion_during_transitions
28-
def assert_has_row():
29-
invocations.invocations_panel_list_items.wait_for_visible()
30-
invocation_rows = invocations.invocations_panel_list_items.all()
31-
assert len(invocation_rows) > 0
32-
return invocation_rows[0]
33-
34-
assert_has_row()
35-
36-
invocations.state_details.assert_absent()
37-
details = invocations.invocations_panel_list_items.all()[0]
38-
details.click()
39-
invocations.state_details.wait_for_visible()
25+
self.invocation_open_latest()
4026

41-
# close invocations panel
42-
gx_selenium_context.components.invocations.activity.wait_for_and_click()
27+
invocations = self.components.invocations
4328

4429
@retry_assertion_during_transitions
4530
def assert_progress_steps_note_contains(text):
@@ -77,3 +62,81 @@ def assert_progress_steps_note_contains(text):
7762
invocations.step_output_collection_element_identifier(element_identifier="forward").wait_for_and_click()
7863
datatype = invocations.step_output_collection_element_datatype(order_index="1").wait_for_text()
7964
assert datatype == "txt"
65+
66+
@selenium_test
67+
@managed_history # failed job messes with some history wait code we probably shouldn't be using
68+
def test_invocation_step_jobs_with_failed_jobs(self):
69+
"""Test invocation step jobs view with mixed successful and failed jobs.
70+
71+
This test verifies:
72+
- Job state counters (ok and error) display correctly for steps with mixed job states
73+
- Filtering by failed jobs works correctly
74+
- Debug tab shows only failed steps
75+
- Failed steps can be expanded in debug view
76+
"""
77+
history_id = self.current_history_id()
78+
self.workflow_populator.run_workflow(
79+
WORKFLOW_KEEP_SUCCESSFUL_DATASETS,
80+
test_data=WORKFLOW_KEEP_SUCCESSFUL_DATASETS_TEST_DATA,
81+
history_id=history_id,
82+
assert_ok=False,
83+
)
84+
85+
# Open the first invocation
86+
self.invocation_open_latest()
87+
88+
# Navigate to Steps tab
89+
invocations = self.components.invocations
90+
invocations.invocation_tab(label="Steps").wait_for_and_click()
91+
92+
# Click on a step with multiple mixed failed and successful jobs
93+
invocations.step_details(order_index="1").wait_for_and_click()
94+
invocations.step_job_details(order_index="1").wait_for_visible()
95+
96+
# Verify job state counters
97+
okay_counter = invocations.step_job_details_state_counter(state="ok").wait_for_visible()
98+
failed_counter = invocations.step_job_details_state_counter(state="error").wait_for_visible()
99+
assert okay_counter.get_attribute("data-count") == "1"
100+
assert failed_counter.get_attribute("data-count") == "1"
101+
self.screenshot("invocation_steps_view_with_failed_jobs")
102+
103+
# Filter by failed jobs
104+
invocations.step_job_details_state_counter(state="error").wait_for_and_click()
105+
self.screenshot("invocation_steps_view_with_failed_jobs_failed_jobs_list")
106+
107+
# Navigate to Debug tab
108+
invocations.invocation_tab(label="Debug").wait_for_and_click()
109+
110+
# Verify the failed step appears here and the successful step doesn't
111+
self.screenshot("invocation_steps_view_with_failed_jobs_debug_landing")
112+
invocations.step_title(order_index=1).wait_for_and_click()
113+
invocations.step_title(order_index=2).assert_absent()
114+
self.screenshot("invocation_steps_view_with_failed_jobs_debug_job_expanded")
115+
116+
def invocation_open_latest(self):
117+
# TODO: migrate retry_assertion_during_transitions to navigates_galaxy.py so this
118+
# can be moved there.
119+
120+
# open invocations panel
121+
self.home()
122+
self.components.invocations.activity.wait_for_and_click()
123+
124+
invocations = self.components.invocations
125+
invocations.invocations_panel_list.wait_for_visible()
126+
127+
@retry_assertion_during_transitions
128+
def assert_has_row():
129+
invocations.invocations_panel_list_items.wait_for_visible()
130+
invocation_rows = invocations.invocations_panel_list_items.all()
131+
assert len(invocation_rows) > 0
132+
return invocation_rows[0]
133+
134+
assert_has_row()
135+
136+
invocations.state_details.assert_absent()
137+
details = invocations.invocations_panel_list_items.all()[0]
138+
details.click()
139+
invocations.state_details.wait_for_visible()
140+
141+
# close invocations panel
142+
self.components.invocations.activity.wait_for_and_click()

0 commit comments

Comments
 (0)