Add E2E tests for PickValueModule workflow editor

7 Selenium/Playwright tests: palette add, mode selection, terminals,
connections, grow-on-connect, conditional roundtrip, output type change.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
John Chilton
2026-03-22 19:15:04 -04:00
co-authored by Claude Opus 4.6
parent 77ebeeab26
commit 27d200e939
2 changed files with 176 additions and 4 deletions
@@ -37,10 +37,10 @@ function cleanToolState(): ToolState {
const emit = defineEmits(["onChange"]);
const modeOptions = [
{ value: "first_non_null", label: "First non-null (error if all null)" },
{ value: "first_or_skip", label: "First non-null (skip if all null)" },
{ value: "the_only_non_null", label: "The only non-null (error if != 1)" },
{ value: "all_non_null", label: "All non-null (as collection)" },
["First non-null (error if all null)", "first_non_null"],
["First non-null (skip if all null)", "first_or_skip"],
["The only non-null (error if != 1)", "the_only_non_null"],
["All non-null (as collection)", "all_non_null"],
];
function onMode(newMode: string) {
@@ -946,6 +946,178 @@ steps:
workflow = self.workflow_populator.download_workflow(workflow_id)
return workflow
def _pick_value_select_mode(self, label):
mode_selector = "div.ui-form-element[id='form-element-mode']"
container = self.wait_for_selector(mode_selector)
trigger = container.find_element(By.CSS_SELECTOR, ".multiselect__select")
trigger.click()
self.sleep_for(self.wait_types.UX_RENDER)
js = """
var label = arguments[0];
var container = document.querySelector('#form-element-mode');
var items = container.querySelectorAll('.multiselect__element');
for (var i = 0; i < items.length; i++) {
if (items[i].textContent.trim() === label) {
items[i].querySelector('.multiselect__option').click();
return true;
}
}
return false;
"""
result = self.execute_script(js, label)
assert result, f"Mode option '{label}' not found"
@selenium_test
def test_pick_value_add_from_palette(self):
self.workflow_create_new(annotation="pick value test")
self.workflow_editor_add_input(item_name="pick_value")
editor = self.components.workflow_editor
editor.node._(label="Pick Value").wait_for_present()
@selenium_test
def test_pick_value_mode_selection(self):
self.workflow_create_new(annotation="pick value mode test")
self.workflow_editor_add_input(item_name="pick_value")
editor = self.components.workflow_editor
node = editor.node._(label="Pick Value")
node.wait_for_and_click()
self._pick_value_select_mode("All non-null (as collection)")
self.sleep_for(self.wait_types.UX_RENDER)
self.assert_workflow_has_changes_and_save()
workflow = self._download_current_workflow()
pick_step = [s for s in workflow["steps"].values() if s["type"] == "pick_value"][0]
tool_state = json.loads(pick_step["tool_state"])
assert tool_state["mode"] == "all_non_null"
@selenium_test
def test_pick_value_terminals(self):
self.workflow_create_new(annotation="pick value terminals test")
self.workflow_editor_add_input(item_name="pick_value")
editor = self.components.workflow_editor
node = editor.node._(label="Pick Value")
node.input_terminal(name="input_0").wait_for_present()
node.input_terminal(name="input_1").wait_for_present()
node.output_terminal(name="output").wait_for_present()
@selenium_test
def test_pick_value_connect_inputs(self):
self.workflow_create_new(annotation="pick value connections test")
self.workflow_editor_add_input(item_name="data_input")
editor = self.components.workflow_editor
editor.label_input.wait_for_and_send_keys("input_data")
self.tool_open("cat1")
self.sleep_for(self.wait_types.UX_RENDER)
editor.label_input.wait_for_and_send_keys("branch_a")
self.workflow_editor_add_input(item_name="pick_value")
editor.label_input.wait_for_and_send_keys("pick")
self.components.workflow_editor.tool_bar.auto_layout.wait_for_and_click()
self.sleep_for(self.wait_types.UX_RENDER)
self.workflow_editor_connect("input_data#output", "branch_a#input1")
self.workflow_editor_connect("branch_a#out_file1", "pick#input_0")
self.assert_connected("branch_a#out_file1", "pick#input_0")
@selenium_test
def test_pick_value_grow_on_connect(self):
self.open_in_workflow_editor(
"""
class: GalaxyWorkflow
inputs:
input_data: data
steps:
branch_a:
tool_id: cat
in:
input1: input_data
branch_b:
tool_id: cat
in:
input1: input_data
pick:
type: pick_value
state:
mode: first_non_null
in:
input_0: branch_a/out_file1
input_1: branch_b/out_file1
"""
)
editor = self.components.workflow_editor
pick_node = editor.node._(label="pick")
pick_node.input_terminal(name="input_0").wait_for_present()
pick_node.input_terminal(name="input_1").wait_for_present()
# With 2 connections, grow-on-connect should have created a 3rd empty terminal
pick_node.input_terminal(name="input_2").wait_for_present()
@selenium_test
def test_pick_value_conditional_workflow_roundtrip(self):
self.open_in_workflow_editor(
"""
class: GalaxyWorkflow
inputs:
input_data: data
steps:
branch_a:
tool_id: cat
in:
input1: input_data
when: $(true)
branch_b:
tool_id: cat
in:
input1: input_data
when: $(false)
pick:
type: pick_value
state:
mode: first_non_null
in:
input_0: branch_a/out_file1
input_1: branch_b/out_file1
"""
)
editor = self.components.workflow_editor
pick_node = editor.node._(label="pick")
pick_node.wait_for_present()
self.assert_connected("branch_a#out_file1", "pick#input_0")
self.assert_connected("branch_b#out_file1", "pick#input_1")
pick_node.output_terminal(name="output").wait_for_present()
workflow = self._download_current_workflow()
pick_step = [s for s in workflow["steps"].values() if s["type"] == "pick_value"][0]
tool_state = json.loads(pick_step["tool_state"])
assert tool_state["mode"] == "first_non_null"
assert len(pick_step["input_connections"]) == 2
@selenium_test
def test_pick_value_output_type_changes_with_mode(self):
self.open_in_workflow_editor(
"""
class: GalaxyWorkflow
inputs:
input_data: data
steps:
branch_a:
tool_id: cat
in:
input1: input_data
pick:
type: pick_value
state:
mode: first_non_null
in:
input_0: branch_a/out_file1
"""
)
editor = self.components.workflow_editor
pick_node = editor.node._(label="pick")
pick_node.wait_for_and_click()
self._pick_value_select_mode("All non-null (as collection)")
self.sleep_for(self.wait_types.UX_RENDER)
self.assert_workflow_has_changes_and_save()
workflow = self._download_current_workflow()
pick_step = [s for s in workflow["steps"].values() if s["type"] == "pick_value"][0]
tool_state = json.loads(pick_step["tool_state"])
assert tool_state["mode"] == "all_non_null"
@selenium_test
def test_editor_create_conditional_step(self):
editor = self.components.workflow_editor