Skip to content

Commit

Permalink
Merge pull request galaxyproject#19182 from jmchilton/selenium_24.2
Browse files Browse the repository at this point in the history
[24.2] release testing - UI tests for new workflow parameters
  • Loading branch information
mvdbeek authored Nov 27, 2024
2 parents bfa28df + a05ec3f commit 2f7c1e5
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 21 deletions.
7 changes: 6 additions & 1 deletion client/src/components/Workflow/Run/WorkflowRun.vue
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,12 @@ defineExpose({
<span>before running this workflow.</span>
</BAlert>
<div v-else>
<BAlert v-if="submissionError" class="mb-4" variant="danger" show>
<BAlert
v-if="submissionError"
class="mb-4"
variant="danger"
data-description="workflow run error"
show>
Workflow submission failed: {{ submissionError }}
</BAlert>
<WorkflowRunFormSimple
Expand Down
2 changes: 2 additions & 0 deletions client/src/utils/navigation/navigation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ tool_form:
parameter_div: 'div.ui-form-element[id="form-element-${parameter}"]'
parameter_error: 'div.ui-form-element[id="form-element-${parameter}"] .ui-form-error-text'
parameter_checkbox: 'div.ui-form-element[id="form-element-${parameter}"] .ui-switch'
parameter_select: 'div.ui-form-element[id="form-element-${parameter}"] .multiselect'
parameter_input: 'div.ui-form-element[id="form-element-${parameter}"] .ui-input'
parameter_textarea: 'div.ui-form-element[id="form-element-${parameter}"] textarea'
parameter_data_input_single: 'div.ui-form-element[id="form-element-${parameter}"] button[title="Single dataset"]'
Expand Down Expand Up @@ -674,6 +675,7 @@ trs_import:
workflow_run:
selectors:
warning: '[data-description="workflow run warning"]'
run_error: '[data-description="workflow run error"]'
input_div: "[step-label='${label}']"
input_data_div: "[step-label='${label}'] .multiselect"
# TODO: put step labels in the DOM ideally
Expand Down
17 changes: 16 additions & 1 deletion lib/galaxy/selenium/navigates_galaxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,19 @@ def rule_builder_enter_source_text(self, json):
text_area_elem.clear()
text_area_elem.send_keys(json)

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_add_parameter_input(self):
self.workflow_editor_add_input(item_name="parameter_input")

def workflow_editor_set_license(self, license: str) -> None:
license_selector = self.components.workflow_editor.license_selector
license_selector.wait_for_and_click()
Expand Down Expand Up @@ -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()
Expand Down
115 changes: 96 additions & 19 deletions lib/galaxy_test/selenium/test_workflow_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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)
Expand All @@ -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()

Expand All @@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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

Expand Down

0 comments on commit 2f7c1e5

Please sign in to comment.