diff --git a/client/src/components/Workflow/Editor/Actions/workflowActions.ts b/client/src/components/Workflow/Editor/Actions/workflowActions.ts index 4418e0a3c519..b0206c25d9e7 100644 --- a/client/src/components/Workflow/Editor/Actions/workflowActions.ts +++ b/client/src/components/Workflow/Editor/Actions/workflowActions.ts @@ -18,13 +18,21 @@ export class LazySetValueAction extends LazyUndoRedoAction { showAttributesCallback; fromValue; toValue; + what: string | null; - constructor(fromValue: T, toValue: T, setValueHandler: (value: T) => void, showCanvasCallback: () => void) { + constructor( + fromValue: T, + toValue: T, + setValueHandler: (value: T) => void, + showCanvasCallback: () => void, + what: string | null + ) { super(); this.fromValue = structuredClone(fromValue); this.toValue = structuredClone(toValue); this.setValueHandler = setValueHandler; this.showAttributesCallback = showCanvasCallback; + this.what = what; } queued() { @@ -46,6 +54,16 @@ export class LazySetValueAction extends LazyUndoRedoAction { this.setValueHandler(this.toValue); } + get dataAttributes(): Record { + if (this.what) { + return { + type: `set-${this.what}`, + }; + } else { + return {}; + } + } + get name() { return this.internalName ?? "modify workflow"; } @@ -61,24 +79,33 @@ export class SetValueActionHandler { showAttributesCallback; lazyAction: LazySetValueAction | null = null; name?: string; + what: string | null; constructor( undoRedoStore: UndoRedoStore, setValueHandler: (value: T) => void, showCanvasCallback: () => void, - name?: string + name?: string, + what: string | null = null ) { this.undoRedoStore = undoRedoStore; this.setValueHandler = setValueHandler; this.showAttributesCallback = showCanvasCallback; this.name = name; + this.what = what; } set(from: T, to: T) { if (this.lazyAction && this.undoRedoStore.isQueued(this.lazyAction)) { this.lazyAction.changeValue(to); } else { - this.lazyAction = new LazySetValueAction(from, to, this.setValueHandler, this.showAttributesCallback); + this.lazyAction = new LazySetValueAction( + from, + to, + this.setValueHandler, + this.showAttributesCallback, + this.what + ); this.lazyAction.name = this.name; this.undoRedoStore.applyLazyAction(this.lazyAction); } diff --git a/client/src/components/Workflow/Editor/Index.vue b/client/src/components/Workflow/Editor/Index.vue index 9506a25386af..6ba440897926 100644 --- a/client/src/components/Workflow/Editor/Index.vue +++ b/client/src/components/Workflow/Editor/Index.vue @@ -324,7 +324,8 @@ export default { undoRedoStore, (value) => (license.value = value), showAttributes, - "set license" + "set license", + "license" ); /** user set license. queues an undo/redo action */ function setLicense(newLicense) { @@ -338,7 +339,8 @@ export default { undoRedoStore, (value) => (creator.value = value), showAttributes, - "set creator" + "set creator", + "creator" ); /** user set creator. queues an undo/redo action */ function setCreator(newCreator) { @@ -350,7 +352,8 @@ export default { undoRedoStore, (value) => (annotation.value = value), showAttributes, - "modify annotation" + "modify annotation", + "annotation" ); /** user set annotation. queues an undo/redo action */ function setAnnotation(newAnnotation) { diff --git a/client/src/utils/navigation/navigation.yml b/client/src/utils/navigation/navigation.yml index 6ba74371bc8f..1cb87a786fe3 100644 --- a/client/src/utils/navigation/navigation.yml +++ b/client/src/utils/navigation/navigation.yml @@ -722,6 +722,8 @@ workflow_editor: action_insert_data_input: ".action[data-type='step-insert'][data-step-type='data_input']" action_insert_data_collection_input: ".action[data-type='step-insert'][data-step-type='data_collection_input']" action_insert_parameter: ".action[data-type='step-insert'][data-step-type='parameter_input']" + action_set_license: ".action[data-type='set-license']" + action_set_annotation: ".action[data-type='set-annotation']" tool_bar: selectors: @@ -743,6 +745,7 @@ workflow_editor: duplicate_selection: "[title='duplicate selected']" delete_selection: "[title='delete selected']" auto_layout: "#auto-layout-button" + attributes: "#activity-workflow-editor-attributes" changes: "#activity-workflow-undo-redo" upgrade_all: "#activity-workflow-upgrade" comment: diff --git a/lib/galaxy/selenium/navigates_galaxy.py b/lib/galaxy/selenium/navigates_galaxy.py index 8d88faca8908..b2d62a2715c2 100644 --- a/lib/galaxy/selenium/navigates_galaxy.py +++ b/lib/galaxy/selenium/navigates_galaxy.py @@ -1212,6 +1212,11 @@ def workflow_editor_set_license(self, license: str) -> None: license_selector_option = self.components.workflow_editor.license_selector_option license_selector_option.wait_for_and_click() + def workflow_editor_license_text(self) -> str: + editor = self.components.workflow_editor + editor.license_selector.wait_for_visible() + return editor.license_current_value.wait_for_text() + def workflow_editor_add_tool_step(self, tool_id: str): self.tool_open(tool_id) @@ -1682,7 +1687,7 @@ def workflow_create_new(self, annotation=None, clear_placeholder=False, save_wor name_component.wait_for_visible().clear() name_component.wait_for_and_send_keys(name) annotation = annotation or self._get_random_name() - self.components.workflow_editor.edit_annotation.wait_for_and_send_keys(annotation) + self.workflow_editor_set_annotation(annotation) if save_workflow: save_button = self.components.workflow_editor.save_button save_button.wait_for_visible() @@ -1691,6 +1696,9 @@ def workflow_create_new(self, annotation=None, clear_placeholder=False, save_wor self.sleep_for(self.wait_types.UX_RENDER) return name + def workflow_editor_set_annotation(self, annotation: str): + self.components.workflow_editor.edit_annotation.wait_for_and_clear_and_send_keys(annotation) + def invocation_index_table_elements(self): invocations = self.components.invocations invocations.invocations_table.wait_for_visible() diff --git a/lib/galaxy_test/selenium/test_workflow_editor.py b/lib/galaxy_test/selenium/test_workflow_editor.py index 1cd746ac9ee8..9239863c8ada 100644 --- a/lib/galaxy_test/selenium/test_workflow_editor.py +++ b/lib/galaxy_test/selenium/test_workflow_editor.py @@ -88,15 +88,13 @@ def test_edit_license(self): editor = self.components.workflow_editor name = self.workflow_create_new() editor.canvas_body.wait_for_visible() - editor.license_selector.wait_for_visible() - assert "Do not specify" in editor.license_current_value.wait_for_text() + assert "Do not specify" in self.workflow_editor_license_text() self.workflow_editor_set_license("MIT") self.workflow_editor_click_save() self.workflow_index_open_with_name(name) - editor.license_selector.wait_for_visible() - assert "MIT" in editor.license_current_value.wait_for_text() + assert "MIT" in self.workflow_editor_license_text() @selenium_test def test_optional_select_data_field(self): @@ -368,13 +366,10 @@ def test_reconnecting_nodes(self): self.assert_connected("input1#output", "first_cat#input1") @selenium_test - def test_editor_change_stack(self): + def test_editor_change_stack_inserting_inputs(self): editor = self.components.workflow_editor - annotation = "change_stack_test" - name = self.workflow_create_new(annotation=annotation) - - self.workflow_editor_set_license("MIT") - self.workflow_editor_click_save() + annotation = "change_stack_test_inserting_inputs" + self.workflow_create_new(annotation=annotation) self.workflow_editor_add_input(item_name="data_input") self.workflow_editor_add_input(item_name="data_collection_input") @@ -413,6 +408,38 @@ def test_editor_change_stack(self): editor.node.by_id(id=1).wait_for_present() editor.node.by_id(id=2).wait_for_present() + @selenium_test + def test_editor_change_stack_set_attributes(self): + editor = self.components.workflow_editor + annotation = "change_stack_test_set_attributes" + name = self.workflow_create_new(annotation=annotation) + + assert "Do not specify" in self.workflow_editor_license_text() + self.workflow_editor_set_license("MIT") + assert "MIT" in self.workflow_editor_license_text() + + editor.tool_bar.changes.wait_for_and_click() + + changes = editor.changes + changes.action_set_license.wait_for_and_click() + # it switches back so this isn't needed per se + # editor.tool_bar.attributes.wait_for_and_click() + assert "Do not specify" in self.workflow_editor_license_text() + + # for annotation we want to reset the change stack to dismiss + # the original setting of the annotation + name = self.workflow_index_open_with_name(name) + + annotation_modified = "change_stack_test_set_attributes modified!!!" + + self.workflow_editor_set_annotation(annotation_modified) + self.assert_wf_annotation_is(annotation_modified) + + editor.tool_bar.changes.wait_for_and_click() + changes.action_set_annotation.wait_for_and_click() + + self.assert_wf_annotation_is(annotation) + @selenium_test def test_rendering_output_collection_connections(self): self.open_in_workflow_editor(WORKFLOW_WITH_OUTPUT_COLLECTION)