diff --git a/client/src/components/Workflow/Run/WorkflowRun.vue b/client/src/components/Workflow/Run/WorkflowRun.vue index 18a9389654eb..dea37e56adc0 100644 --- a/client/src/components/Workflow/Run/WorkflowRun.vue +++ b/client/src/components/Workflow/Run/WorkflowRun.vue @@ -195,7 +195,12 @@ defineExpose({ before running this workflow.
- + Workflow submission failed: {{ submissionError }} None: license_selector = self.components.workflow_editor.license_selector license_selector.wait_for_and_click() @@ -1618,7 +1631,9 @@ def workflow_run_ensure_expanded(self): workflow_run.expand_form_link.wait_for_and_click() workflow_run.expanded_form.wait_for_visible() - def workflow_create_new(self, annotation=None, clear_placeholder=False, save_workflow=True): + def workflow_create_new( + self, annotation: Optional[str] = None, clear_placeholder: bool = False, save_workflow: bool = True + ): self.workflow_index_open() self.sleep_for(self.wait_types.UX_RENDER) self.click_button_new_workflow() diff --git a/lib/galaxy_test/selenium/test_workflow_editor.py b/lib/galaxy_test/selenium/test_workflow_editor.py index af8ba29fbc53..cbd3c5f0f31b 100644 --- a/lib/galaxy_test/selenium/test_workflow_editor.py +++ b/lib/galaxy_test/selenium/test_workflow_editor.py @@ -69,7 +69,7 @@ def test_basics(self): def test_edit_annotation(self): editor = self.components.workflow_editor annotation = "new_annotation_test" - name = self.workflow_create_new(annotation=annotation) + name = self.create_and_wait_for_new_workflow_in_editor(annotation=annotation) edit_annotation = self.components.workflow_editor.edit_annotation self.assert_wf_annotation_is(annotation) @@ -83,9 +83,7 @@ def test_edit_annotation(self): @selenium_test def test_edit_name(self): - editor = self.components.workflow_editor - name = self.workflow_create_new() - editor.canvas_body.wait_for_visible() + name = self.create_and_wait_for_new_workflow_in_editor() new_name = self._get_random_name() edit_name = self.components.workflow_editor.edit_name edit_name.wait_for_and_send_keys(new_name) @@ -97,8 +95,7 @@ def test_edit_name(self): @selenium_test def test_edit_license(self): editor = self.components.workflow_editor - name = self.workflow_create_new() - editor.canvas_body.wait_for_visible() + name = self.create_and_wait_for_new_workflow_in_editor() editor.license_selector.wait_for_visible() assert "Do not specify" in editor.license_current_value.wait_for_text() @@ -109,6 +106,87 @@ def test_edit_license(self): editor.license_selector.wait_for_visible() assert "MIT" in editor.license_current_value.wait_for_text() + @selenium_test + def test_parameter_regex_validation(self): + editor = self.components.workflow_editor + workflow_run = self.components.workflow_run + + parameter_name = "text_param" + name = self.create_and_wait_for_new_workflow_in_editor() + self.workflow_editor_add_parameter_input() + editor.label_input.wait_for_and_send_keys(parameter_name) + # this really should be parameterized with the repeat name + self.components.tool_form.repeat_insert.wait_for_and_click() + self.components.tool_form.parameter_input( + parameter="parameter_definition|validators_0|regex_match" + ).wait_for_and_send_keys("moocow.*") + self.components.tool_form.parameter_input( + parameter="parameter_definition|validators_0|regex_doc" + ).wait_for_and_send_keys("input must start with moocow") + self.save_after_node_form_changes() + + self.workflow_run_with_name(name) + self.sleep_for(self.wait_types.UX_TRANSITION) + input_element = workflow_run.simplified_input(label=parameter_name).wait_for_and_click() + input_element.send_keys("startswrong") + workflow_run.run_workflow_disabled.wait_for_absent() + workflow_run.run_error.assert_absent_or_hidden() + self.workflow_run_submit() + element = workflow_run.run_error.wait_for_present() + assert "input must start with moocow" in element.text + + @selenium_test + def test_int_parameter_minimum_validation(self): + editor = self.components.workflow_editor + workflow_run = self.components.workflow_run + + parameter_name = "int_param" + name = self.create_and_wait_for_new_workflow_in_editor() + self.workflow_editor_add_parameter_input() + editor.label_input.wait_for_and_send_keys(parameter_name) + select_field = self.components.tool_form.parameter_select(parameter="parameter_definition|parameter_type") + self.select_set_value(select_field, "integer") + self.components.tool_form.parameter_input(parameter="parameter_definition|min").wait_for_and_send_keys("4") + self.save_after_node_form_changes() + + self.workflow_run_with_name(name) + self.sleep_for(self.wait_types.UX_TRANSITION) + input_element = workflow_run.simplified_input(label=parameter_name).wait_for_and_click() + input_element.send_keys("3") + workflow_run.run_workflow_disabled.wait_for_absent() + workflow_run.run_error.assert_absent_or_hidden() + self.workflow_run_submit() + element = workflow_run.run_error.wait_for_present() + # follow up with a bigger PR to just make this (4 <= value) right? need to set default message + # in parameter validators + assert "Value ('3') must fulfill (4 <= value <= +infinity)" in element.text, element.text + + @selenium_test + def test_float_parameter_maximum_validation(self): + editor = self.components.workflow_editor + workflow_run = self.components.workflow_run + + parameter_name = "float_param" + name = self.create_and_wait_for_new_workflow_in_editor() + self.workflow_editor_add_parameter_input() + editor.label_input.wait_for_and_send_keys(parameter_name) + select_field = self.components.tool_form.parameter_select(parameter="parameter_definition|parameter_type") + self.select_set_value(select_field, "float") + self.components.tool_form.parameter_input(parameter="parameter_definition|max").wait_for_and_send_keys("3.14") + self.save_after_node_form_changes() + + self.workflow_run_with_name(name) + self.sleep_for(self.wait_types.UX_TRANSITION) + input_element = workflow_run.simplified_input(label=parameter_name).wait_for_and_click() + input_element.send_keys("3.2") + workflow_run.run_workflow_disabled.wait_for_absent() + workflow_run.run_error.assert_absent_or_hidden() + self.workflow_run_submit() + element = workflow_run.run_error.wait_for_present() + # see message in test test_int_parameter_minimum_validation about making this a little more human + # friendly. + assert "Value ('3.2') must fulfill (-infinity <= value <= 3.14)" in element.text, element.text + @selenium_test def test_optional_select_data_field(self): editor = self.components.workflow_editor @@ -120,9 +198,7 @@ def test_optional_select_data_field(self): node.title.wait_for_and_click() self.components.tool_form.parameter_checkbox(parameter="select_single").wait_for_and_click() self.components.tool_form.parameter_input(parameter="select_single").wait_for_and_send_keys("parameter value") - # onSetData does an extra POST to build_modules, so we need to wait for that ... - self.sleep_for(self.wait_types.UX_RENDER) - self.assert_workflow_has_changes_and_save() + self.save_after_node_form_changes() workflow = self.workflow_populator.download_workflow(workflow_id) tool_state = json.loads(workflow["steps"]["0"]["tool_state"]) assert tool_state["select_single"] == "parameter value" @@ -1329,6 +1405,17 @@ def test_editor_selection(self): assert editor.tool_bar.selection_count.wait_for_visible().text.find("1 comment") != -1 + def create_and_wait_for_new_workflow_in_editor(self, annotation: Optional[str] = None) -> str: + editor = self.components.workflow_editor + name = self.workflow_create_new(annotation=annotation) + editor.canvas_body.wait_for_visible() + return name + + def save_after_node_form_changes(self): + # onSetData does an extra POST to build_modules, so we need to wait for that ... + self.sleep_for(self.wait_types.UX_RENDER) + self.assert_workflow_has_changes_and_save() + def get_node_position(self, label: str): node = self.components.workflow_editor.node._(label=label).wait_for_present() @@ -1442,16 +1529,6 @@ def workflow_editor_source_sink_terminal_ids(self, source, sink): return source_id, sink_id - def workflow_editor_add_input(self, item_name="data_input"): - editor = self.components.workflow_editor - - # Make sure we're on the workflow editor and not clicking the main tool panel. - editor.canvas_body.wait_for_visible() - - editor.tool_menu.wait_for_visible() - editor.tool_menu_section_link(section_name="inputs").wait_for_and_click() - editor.tool_menu_item_link(item_name=item_name).wait_for_and_click() - def workflow_editor_destroy_connection(self, sink): editor = self.components.workflow_editor