Selenium test lightly exercising workflow debug, failed jobs, etc...

This commit is contained in:
John Chilton
2025-10-14 13:54:51 -04:00
parent 425ddc908a
commit 94dcb86ee8
5 changed files with 128 additions and 54 deletions
@@ -11,7 +11,11 @@ const props = defineProps<{
</script>
<template>
<span class="d-flex align-items-center">
<span
class="d-flex align-items-center"
data-description="invocation step state counter"
:data-state="state"
:data-count="jobCount">
<FontAwesomeIcon
v-if="iconClasses[props.state]"
:icon="iconClasses[props.state]?.icon"
@@ -1027,6 +1027,7 @@ invocations:
selector: '//span[contains(@class, "content-title name")][text()="${element_identifier}"]'
step_output_collection_element_datatype: '[data-step="${order_index}"] .invocation-step-output-collection-details .not-loading .datatype .value'
step_job_details: '[data-step="${order_index}"] .invocation-step-job-details'
step_job_details_state_counter: '[data-description="invocation step state counter"][data-state="${state}"]'
step_job_information: '[data-step="${order_index}"] .invocation-step-job-details .info_data_table'
step_job_information_tool_id: '[data-step="${order_index}"] .invocation-step-job-details .info_data_table #galaxy-tool-id'
export_tab: '.invocation-export-tab'
+4 -30
View File
@@ -41,6 +41,8 @@ from galaxy_test.base.workflow_fixtures import (
NESTED_WORKFLOW_WITH_CONDITIONAL_SUBWORKFLOW_AND_DISCONNECTED_MAP_OVER_SOURCE,
WORKFLOW_FLAT_CROSS_PRODUCT,
WORKFLOW_INPUTS_AS_OUTPUTS,
WORKFLOW_KEEP_SUCCESSFUL_DATASETS,
WORKFLOW_KEEP_SUCCESSFUL_DATASETS_TEST_DATA,
WORKFLOW_LIST_PAIRED_INPUT_TO_TYPE_SOURCE,
WORKFLOW_NESTED_REPLACEMENT_PARAMETER,
WORKFLOW_NESTED_RUNTIME_PARAMETER,
@@ -3790,36 +3792,8 @@ input_c:
def test_keep_success_mapping_error(self):
with self.dataset_populator.test_history() as history_id:
summary = self._run_workflow(
"""
class: GalaxyWorkflow
inputs:
input_c: collection
steps:
mixed_collection:
tool_id: exit_code_from_file
in:
input: input_c
filtered_collection:
tool_id: "__KEEP_SUCCESS_DATASETS__"
in:
input: mixed_collection/out_file1
cat:
tool_id: cat1
in:
input1: filtered_collection/output
""",
test_data="""
input_c:
collection_type: list
elements:
- identifier: i1
content: "0"
- identifier: i2
content: "1"
""",
WORKFLOW_KEEP_SUCCESSFUL_DATASETS,
test_data=WORKFLOW_KEEP_SUCCESSFUL_DATASETS_TEST_DATA,
history_id=history_id,
wait=True,
assert_ok=False,
+32
View File
@@ -1280,3 +1280,35 @@ WORKFLOW_WITH_DATA_TAG_FILTER = r"""{
"uuid": "03a95ebe-af1e-4628-ac2f-e7553babfb2f",
"version": 3
}"""
WORKFLOW_KEEP_SUCCESSFUL_DATASETS = """
class: GalaxyWorkflow
inputs:
input_c: collection
steps:
mixed_collection:
tool_id: exit_code_from_file
in:
input: input_c
filtered_collection:
tool_id: "__KEEP_SUCCESS_DATASETS__"
in:
input: mixed_collection/out_file1
cat:
tool_id: cat
in:
input1: filtered_collection/output
"""
WORKFLOW_KEEP_SUCCESSFUL_DATASETS_TEST_DATA = """
input_c:
collection_type: list
elements:
- identifier: i1
content: "0"
- identifier: i2
content: "1"
"""
@@ -1,5 +1,10 @@
from galaxy_test.base.workflow_fixtures import WORKFLOW_WITH_OUTPUT_COLLECTION
from galaxy_test.base.workflow_fixtures import (
WORKFLOW_KEEP_SUCCESSFUL_DATASETS,
WORKFLOW_KEEP_SUCCESSFUL_DATASETS_TEST_DATA,
WORKFLOW_WITH_OUTPUT_COLLECTION,
)
from .framework import (
managed_history,
retry_assertion_during_transitions,
selenium_test,
SeleniumTestCase,
@@ -17,29 +22,9 @@ class TestWorkflowInvocationDetails(SeleniumTestCase):
WORKFLOW_WITH_OUTPUT_COLLECTION, history_id=history_id, assert_ok=True, wait=True
)
# open invocations panel
self.home()
gx_selenium_context.components.invocations.activity.wait_for_and_click()
self.invocation_open_latest()
invocations = gx_selenium_context.components.invocations
invocations.invocations_panel_list.wait_for_visible()
@retry_assertion_during_transitions
def assert_has_row():
invocations.invocations_panel_list_items.wait_for_visible()
invocation_rows = invocations.invocations_panel_list_items.all()
assert len(invocation_rows) > 0
return invocation_rows[0]
assert_has_row()
invocations.state_details.assert_absent()
details = invocations.invocations_panel_list_items.all()[0]
details.click()
invocations.state_details.wait_for_visible()
# close invocations panel
gx_selenium_context.components.invocations.activity.wait_for_and_click()
invocations = self.components.invocations
@retry_assertion_during_transitions
def assert_progress_steps_note_contains(text):
@@ -77,3 +62,81 @@ class TestWorkflowInvocationDetails(SeleniumTestCase):
invocations.step_output_collection_element_identifier(element_identifier="forward").wait_for_and_click()
datatype = invocations.step_output_collection_element_datatype(order_index="1").wait_for_text()
assert datatype == "txt"
@selenium_test
@managed_history # failed job messes with some history wait code we probably shouldn't be using
def test_invocation_step_jobs_with_failed_jobs(self):
"""Test invocation step jobs view with mixed successful and failed jobs.
This test verifies:
- Job state counters (ok and error) display correctly for steps with mixed job states
- Filtering by failed jobs works correctly
- Debug tab shows only failed steps
- Failed steps can be expanded in debug view
"""
history_id = self.current_history_id()
self.workflow_populator.run_workflow(
WORKFLOW_KEEP_SUCCESSFUL_DATASETS,
test_data=WORKFLOW_KEEP_SUCCESSFUL_DATASETS_TEST_DATA,
history_id=history_id,
assert_ok=False,
)
# Open the first invocation
self.invocation_open_latest()
# Navigate to Steps tab
invocations = self.components.invocations
invocations.invocation_tab(label="Steps").wait_for_and_click()
# Click on a step with multiple mixed failed and successful jobs
invocations.step_details(order_index="1").wait_for_and_click()
invocations.step_job_details(order_index="1").wait_for_visible()
# Verify job state counters
okay_counter = invocations.step_job_details_state_counter(state="ok").wait_for_visible()
failed_counter = invocations.step_job_details_state_counter(state="error").wait_for_visible()
assert okay_counter.get_attribute("data-count") == "1"
assert failed_counter.get_attribute("data-count") == "1"
self.screenshot("invocation_steps_view_with_failed_jobs")
# Filter by failed jobs
invocations.step_job_details_state_counter(state="error").wait_for_and_click()
self.screenshot("invocation_steps_view_with_failed_jobs_failed_jobs_list")
# Navigate to Debug tab
invocations.invocation_tab(label="Debug").wait_for_and_click()
# Verify the failed step appears here and the successful step doesn't
self.screenshot("invocation_steps_view_with_failed_jobs_debug_landing")
invocations.step_title(order_index=1).wait_for_and_click()
invocations.step_title(order_index=2).assert_absent()
self.screenshot("invocation_steps_view_with_failed_jobs_debug_job_expanded")
def invocation_open_latest(self):
# TODO: migrate retry_assertion_during_transitions to navigates_galaxy.py so this
# can be moved there.
# open invocations panel
self.home()
self.components.invocations.activity.wait_for_and_click()
invocations = self.components.invocations
invocations.invocations_panel_list.wait_for_visible()
@retry_assertion_during_transitions
def assert_has_row():
invocations.invocations_panel_list_items.wait_for_visible()
invocation_rows = invocations.invocations_panel_list_items.all()
assert len(invocation_rows) > 0
return invocation_rows[0]
assert_has_row()
invocations.state_details.assert_absent()
details = invocations.invocations_panel_list_items.all()[0]
details.click()
invocations.state_details.wait_for_visible()
# close invocations panel
self.components.invocations.activity.wait_for_and_click()