diff --git a/cypress/e2e/17-workflow-tags.cy.ts b/cypress/e2e/17-workflow-tags.cy.ts new file mode 100644 index 0000000000..87926bf0f2 --- /dev/null +++ b/cypress/e2e/17-workflow-tags.cy.ts @@ -0,0 +1,96 @@ +import { WorkflowPage } from '../pages'; + +const wf = new WorkflowPage(); + +const TEST_TAGS = ['Tag 1', 'Tag 2', 'Tag 3']; + +describe('Workflow tags', () => { + beforeEach(() => { + cy.resetAll(); + cy.skipSetup(); + wf.actions.visit(); + cy.waitForLoad(); + }); + + it('should create and attach tags inline', () => { + wf.getters.createTagButton().click(); + wf.actions.addTags(TEST_TAGS); + wf.getters.tagPills().should('have.length', TEST_TAGS.length); + wf.getters.nthTagPill(1).click(); + wf.actions.addTags('Tag 4'); + wf.getters.tagPills().should('have.length', TEST_TAGS.length + 1); + wf.getters.isWorkflowSaved(); + }); + + it('should create tags via modal', () => { + wf.actions.openTagManagerModal(); + + const [first, second] = TEST_TAGS; + + cy.contains('Create a tag').click(); + cy.getByTestId('tags-table').find('input').type(first).type('{enter}'); + cy.contains('Add new').click(); + cy.wait(300); + cy.getByTestId('tags-table').find('input').type(second).type('{enter}'); + cy.contains('Done').click(); + + wf.getters.createTagButton().click(); + wf.getters.tagsInDropdown().should('have.length', 2); // two stored + wf.getters.tagPills().should('have.length', 0); // none attached + }); + + it('should delete a tag via modal', () => { + wf.actions.openTagManagerModal(); + + const [first] = TEST_TAGS; + + cy.contains('Create a tag').click(); + cy.getByTestId('tags-table').find('input').type(first).type('{enter}'); + cy.getByTestId('delete-tag-button').click({ force: true }); + cy.wait(300); + cy.contains('Delete tag').click(); + cy.contains('Done').click(); + wf.getters.createTagButton().click(); + wf.getters.tagsInDropdown().should('have.length', 0); // none stored + wf.getters.tagPills().should('have.length', 0); // none attached + }); + + it('should update a tag via modal', () => { + wf.actions.openTagManagerModal(); + + const [first] = TEST_TAGS; + + cy.contains('Create a tag').click(); + cy.getByTestId('tags-table').find('input').type(first).type('{enter}'); + cy.getByTestId('edit-tag-button').click({ force: true }); + cy.wait(300); + cy.getByTestId('tags-table') + .find('.el-input--large') + .should('be.visible') + .type(' Updated') + .type('{enter}'); + cy.contains('Done').click(); + wf.getters.createTagButton().click(); + wf.getters.tagsInDropdown().should('have.length', 1); // one stored + wf.getters.tagsInDropdown().contains('Updated').should('exist'); + wf.getters.tagPills().should('have.length', 0); // none attached + }); + + it('should detach a tag inline by clicking on X on tag pill', () => { + wf.getters.createTagButton().click(); + wf.actions.addTags(TEST_TAGS); + wf.getters.nthTagPill(1).click(); + wf.getters.tagsDropdown().find('.el-tag__close').first().click(); + cy.get('body').type('{enter}'); + wf.getters.tagPills().should('have.length', TEST_TAGS.length - 1); + }); + + it('should detach a tag inline by clicking on dropdown list item', () => { + wf.getters.createTagButton().click(); + wf.actions.addTags(TEST_TAGS); + wf.getters.nthTagPill(1).click(); + wf.getters.tagsDropdown().find('li.selected').first().click(); + cy.get('body').type('{enter}'); + wf.getters.tagPills().should('have.length', TEST_TAGS.length - 1); + }); +}); diff --git a/cypress/e2e/7-workflow-actions.cy.ts b/cypress/e2e/7-workflow-actions.cy.ts index eb4ff08b65..aeb3752ec2 100644 --- a/cypress/e2e/7-workflow-actions.cy.ts +++ b/cypress/e2e/7-workflow-actions.cy.ts @@ -7,7 +7,6 @@ import { import { WorkflowPage as WorkflowPageClass } from '../pages/workflow'; const NEW_WORKFLOW_NAME = 'Something else'; -const TEST_WF_TAGS = ['Tag 1', 'Tag 2', 'Tag 3']; const IMPORT_WORKFLOW_URL = 'https://www.jsonkeeper.com/b/FNB0#.json'; const DUPLICATE_WORKFLOW_NAME = 'Duplicated workflow'; const DUPLICATE_WORKFLOW_TAG = 'Duplicate'; @@ -66,40 +65,6 @@ describe('Workflow Actions', () => { .should('eq', NEW_WORKFLOW_NAME); }); - it('should add tags', () => { - WorkflowPage.getters.newTagLink().click(); - WorkflowPage.actions.addTags(TEST_WF_TAGS); - WorkflowPage.getters.isWorkflowSaved(); - WorkflowPage.getters.workflowTagElements().should('have.length', TEST_WF_TAGS.length); - }); - - it('should add more tags', () => { - WorkflowPage.getters.newTagLink().click(); - WorkflowPage.actions.addTags(TEST_WF_TAGS); - WorkflowPage.getters.isWorkflowSaved(); - WorkflowPage.getters.firstWorkflowTagElement().click(); - WorkflowPage.actions.addTags(['Another one']); - WorkflowPage.getters.workflowTagElements().should('have.length', TEST_WF_TAGS.length + 1); - }); - - it('should remove tags by clicking X in tag', () => { - WorkflowPage.getters.newTagLink().click(); - WorkflowPage.actions.addTags(TEST_WF_TAGS); - WorkflowPage.getters.firstWorkflowTagElement().click(); - WorkflowPage.getters.workflowTagsContainer().find('.el-tag__close').first().click(); - cy.get('body').type('{enter}'); - WorkflowPage.getters.workflowTagElements().should('have.length', TEST_WF_TAGS.length - 1); - }); - - it('should remove tags from dropdown', () => { - WorkflowPage.getters.newTagLink().click(); - WorkflowPage.actions.addTags(TEST_WF_TAGS); - WorkflowPage.getters.firstWorkflowTagElement().click(); - WorkflowPage.getters.workflowTagsDropdown().find('li.selected').first().click(); - cy.get('body').type('{enter}'); - WorkflowPage.getters.workflowTagElements().should('have.length', TEST_WF_TAGS.length - 1); - }); - it('should copy nodes', () => { WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME); WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME); diff --git a/cypress/pages/workflow.ts b/cypress/pages/workflow.ts index 6f4f49727b..8a6a78c3a7 100644 --- a/cypress/pages/workflow.ts +++ b/cypress/pages/workflow.ts @@ -12,11 +12,12 @@ export class WorkflowPage extends BasePage { workflowTagsContainer: () => cy.getByTestId('workflow-tags-container'), workflowTagsInput: () => this.getters.workflowTagsContainer().then(($el) => cy.wrap($el.find('input').first())), - workflowTagElements: () => cy.get('[data-test-id="workflow-tags-container"] span.tags > span'), - firstWorkflowTagElement: () => - cy.get('[data-test-id="workflow-tags-container"] span.tags > span:nth-child(1)'), - workflowTagsDropdown: () => cy.getByTestId('workflow-tags-dropdown'), - newTagLink: () => cy.getByTestId('new-tag-link'), + tagPills: () => cy.get('[data-test-id="workflow-tags-container"] span.tags > span'), + nthTagPill: (n: number) => + cy.get(`[data-test-id="workflow-tags-container"] span.tags > span:nth-child(${n})`), + tagsDropdown: () => cy.getByTestId('workflow-tags-dropdown'), + tagsInDropdown: () => cy.getByTestId('workflow-tags-dropdown').find('li').filter('.tag'), + createTagButton: () => cy.getByTestId('new-tag-link'), saveButton: () => cy.getByTestId('workflow-save-button'), nodeCreatorSearchBar: () => cy.getByTestId('node-creator-search-bar'), nodeCreatorPlusButton: () => cy.getByTestId('node-creator-plus-button'), @@ -95,9 +96,13 @@ export class WorkflowPage extends BasePage { ndvParameters: () => cy.getByTestId('parameter-item'), nodeCredentialsLabel: () => cy.getByTestId('credentials-label'), getConnectionBetweenNodes: (sourceNodeName: string, targetNodeName: string) => - cy.get(`.jtk-connector[data-source-node="${sourceNodeName}"][data-target-node="${targetNodeName}"]`), + cy.get( + `.jtk-connector[data-source-node="${sourceNodeName}"][data-target-node="${targetNodeName}"]`, + ), getConnectionActionsBetweenNodes: (sourceNodeName: string, targetNodeName: string) => - cy.get(`.connection-actions[data-source-node="${sourceNodeName}"][data-target-node="${targetNodeName}"]`), + cy.get( + `.connection-actions[data-source-node="${sourceNodeName}"][data-target-node="${targetNodeName}"]`, + ), }; actions = { visit: () => { @@ -132,6 +137,10 @@ export class WorkflowPage extends BasePage { cy.contains('Expression').invoke('show').click(); cy.getByTestId('expander').invoke('show').click(); }, + openTagManagerModal: () => { + this.getters.createTagButton().click(); + this.getters.tagsDropdown().find('li.manage-tags').first().click(); + }, openInlineExpressionEditor: () => { cy.contains('Expression').invoke('show').click(); this.getters.inlineExpressionEditorInput().click(); @@ -161,7 +170,9 @@ export class WorkflowPage extends BasePage { cy.get('body').type(newName); cy.get('body').type('{enter}'); }, - addTags: (tags: string[]) => { + addTags: (tags: string | string[]) => { + if (!Array.isArray(tags)) tags = [tags]; + tags.forEach((tag) => { this.getters.workflowTagsInput().type(tag); this.getters.workflowTagsInput().type('{enter}'); @@ -200,12 +211,24 @@ export class WorkflowPage extends BasePage { }, addNodeBetweenNodes: (sourceNodeName: string, targetNodeName: string, newNodeName: string) => { this.getters.getConnectionBetweenNodes(sourceNodeName, targetNodeName).first().realHover(); - this.getters.getConnectionActionsBetweenNodes(sourceNodeName, targetNodeName).find('.add').first().click({ force: true }); + this.getters + .getConnectionActionsBetweenNodes(sourceNodeName, targetNodeName) + .find('.add') + .first() + .click({ force: true }); this.actions.addNodeToCanvas(newNodeName, false); }, - deleteNodeBetweenNodes: (sourceNodeName: string, targetNodeName: string, newNodeName: string) => { + deleteNodeBetweenNodes: ( + sourceNodeName: string, + targetNodeName: string, + newNodeName: string, + ) => { this.getters.getConnectionBetweenNodes(sourceNodeName, targetNodeName).first().realHover(); - this.getters.getConnectionActionsBetweenNodes(sourceNodeName, targetNodeName).find('.delete').first().click({ force: true }); + this.getters + .getConnectionActionsBetweenNodes(sourceNodeName, targetNodeName) + .find('.delete') + .first() + .click({ force: true }); }, }; } diff --git a/packages/editor-ui/src/components/TagsManager/TagsView/TagsTable.vue b/packages/editor-ui/src/components/TagsManager/TagsView/TagsTable.vue index 3c6cf43faf..7ecacac24c 100644 --- a/packages/editor-ui/src/components/TagsManager/TagsView/TagsTable.vue +++ b/packages/editor-ui/src/components/TagsManager/TagsView/TagsTable.vue @@ -90,12 +90,14 @@ :title="$locale.baseText('tagsTable.editTag')" @click.stop="enableUpdate(scope.row)" icon="pen" + data-test-id="edit-tag-button" /> diff --git a/packages/editor-ui/src/components/TagsManager/TagsView/TagsView.vue b/packages/editor-ui/src/components/TagsManager/TagsView/TagsView.vue index 1348b26519..02a33ab4e3 100644 --- a/packages/editor-ui/src/components/TagsManager/TagsView/TagsView.vue +++ b/packages/editor-ui/src/components/TagsManager/TagsView/TagsView.vue @@ -17,6 +17,7 @@ @cancelOperation="cancelOperation" @applyOperation="applyOperation" ref="tagsTable" + data-test-id="tags-table" />