Skip to content

Commit

Permalink
test(editor): Add more workflow actions tests (#4799)
Browse files Browse the repository at this point in the history
* ⚡ Making workflow actions tests skip setup, changing suite number
* 🔥 Removing unnecessary imports and vars
* ✅ Adding workflow tags and copy/paste tests
* ✅ Added tests for copying and pasting nodes
* Update cypress/support/commands.ts
Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
* 👌 Moving paste data to fixtures
Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
  • Loading branch information
MiloradFilipovic authored Dec 5, 2022
1 parent 1b7952a commit e07e32f
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 79 deletions.
74 changes: 0 additions & 74 deletions cypress/e2e/5-workflow-actions.cy.ts

This file was deleted.

107 changes: 107 additions & 0 deletions cypress/e2e/7-workflow-actions.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';

const NEW_WORKFLOW_NAME = 'Something else';
const MANUAL_TRIGGER_NODE_NAME = 'Manual Trigger';
const SCHEDULE_TRIGGER_NODE_NAME = 'Schedule Trigger';
const CODE_NODE = 'Code'
const TEST_WF_TAGS = ['Tag 1', 'Tag 2', 'Tag 3'];

const WorkflowPage = new WorkflowPageClass();

describe('Workflow Actions', () => {
beforeEach(() => {
cy.resetAll();
cy.skipSetup();
WorkflowPage.actions.visit();
});

it('should be able to save on button click', () => {
WorkflowPage.actions.saveWorkflowOnButtonClick();
WorkflowPage.getters.isWorkflowSaved();
});

it('should save workflow on keyboard shortcut', () => {
WorkflowPage.actions.saveWorkflowUsingKeyboardShortcut();
WorkflowPage.getters.isWorkflowSaved();
});

it('should not be able to activate unsaved workflow', () => {
WorkflowPage.getters.activatorSwitch().find('input').first().should('be.disabled');
});

it('should not be able to activate workflow without trigger node', () => {
// Manual trigger is not enough to activate the workflow
WorkflowPage.actions.addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
WorkflowPage.actions.saveWorkflowOnButtonClick();
WorkflowPage.getters.activatorSwitch().find('input').first().should('be.disabled');
});

it('should be able to activate workflow', () => {
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
WorkflowPage.actions.saveWorkflowOnButtonClick();
WorkflowPage.actions.activateWorkflow();
WorkflowPage.getters.isWorkflowActivated();
});

it('should save new workflow after renaming', () => {
WorkflowPage.actions.renameWorkflow(NEW_WORKFLOW_NAME);
WorkflowPage.getters.isWorkflowSaved();
});

it('should rename workflow', () => {
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
WorkflowPage.actions.saveWorkflowOnButtonClick();
WorkflowPage.actions.renameWorkflow(NEW_WORKFLOW_NAME);
WorkflowPage.getters.isWorkflowSaved();
WorkflowPage.getters.workflowNameInputContainer().invoke('attr', 'title').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.workflowTagElements().first().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.workflowTagElements().first().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.workflowTagElements().first().click();
WorkflowPage.getters.workflowTagsDropdown().find('li').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);
cy.get('body').type('{meta}', { release: false }).type('a');
cy.get('body').type('{meta}', { release: false }).type('c');
WorkflowPage.getters.successToast().should('exist');
});

it('should paste nodes', () => {
cy.fixture('Test_workflow-actions_paste-data.json').then(data => {
cy.get('body').paste(JSON.stringify(data));
WorkflowPage.getters.canvasNodes().should('have.have.length', 2);
});
});

});
37 changes: 37 additions & 0 deletions cypress/fixtures/Test_workflow-actions_paste-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"meta": {
"instanceId": "1a30c82b98a30444ad25bce513655a5e02be772d361403542c23172be6062f04"
},
"nodes": [{
"parameters": {
"rule": {
"interval": [{}]
}
},
"id": "a898563b-d2a4-4b15-a979-366872e801b0",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [420, 260]
}, {
"parameters": {
"options": {}
},
"id": "b9a13e3d-bfa5-4873-959f-fd3d67e380d9",
"name": "Set",
"type": "n8n-nodes-base.set",
"typeVersion": 1,
"position": [640, 260]
}],
"connections": {
"Schedule Trigger": {
"main": [
[{
"node": "Set",
"type": "main",
"index": 0
}]
]
}
}
}
15 changes: 10 additions & 5 deletions cypress/pages/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { BasePage } from './base';
export class WorkflowPage extends BasePage {
url = '/workflow/new';
getters = {
workflowNameInputContainer: () => cy
.getByTestId('workflow-name-input', { timeout: 5000 }),
workflowNameInputContainer: () => cy.getByTestId('workflow-name-input', { timeout: 5000 }),
workflowNameInput: () => this.getters.workflowNameInputContainer().then(($el) => cy.wrap($el.find('input'))),
workflowImportInput: () => cy.getByTestId('workflow-import-input'),
workflowTags: () => cy.getByTestId('workflow-tags'),
workflowTagsContainer: () => cy.getByTestId('workflow-tags-container'),
workflowTagsInput: () => this.getters.workflowTagsContainer().then(($el) => cy.wrap($el.find('input').first())),
workflowTagElements: () => this.getters.workflowTagsContainer().find('span.tags').children(),
workflowTagsDropdown: () => cy.getByTestId('workflow-tags-dropdown'),
newTagLink: () => cy.getByTestId('new-tag-link'),
saveButton: () => cy.getByTestId('workflow-save-button'),
nodeCreatorSearchBar: () => cy.getByTestId('node-creator-search-bar'),
Expand All @@ -29,6 +31,10 @@ export class WorkflowPage extends BasePage {
isWorkflowActivated: () => this.getters.activatorSwitch().should('have.class', 'is-checked'),
expressionModalInput: () => cy.getByTestId('expression-modal-input'),
expressionModalOutput: () => cy.getByTestId('expression-modal-output'),

nodeViewRoot: () => cy.getByTestId('node-view-root'),
copyPasteInput: () => cy.getByTestId('hidden-copy-paste'),
canvasNodes: () => cy.getByTestId('canvas-node'),
};
actions = {
visit: () => {
Expand Down Expand Up @@ -86,10 +92,9 @@ export class WorkflowPage extends BasePage {
cy.get('body').type('{enter}');
},
addTags: (tags: string[]) => {
this.getters.newTagLink().click();
tags.forEach(tag => {
cy.get('body').type(tag);
cy.get('body').type('{enter}');
this.getters.workflowTagsInput().type(tag);
this.getters.workflowTagsInput().type('{enter}');
});
cy.get('body').type('{enter}');
},
Expand Down
12 changes: 12 additions & 0 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,15 @@ Cypress.Commands.add('resetAll', () => {
Cypress.Commands.add('setupOwner', (payload) => {
cy.task('setup-owner', payload);
});

Cypress.Commands.add('paste', { prevSubject: true }, (selector, pastePayload) => {
// https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event
cy.wrap(selector).then($destination => {
const pasteEvent = Object.assign(new Event('paste', { bubbles: true, cancelable: true }), {
clipboardData: {
getData: () => pastePayload
}
});
$destination[0].dispatchEvent(pasteEvent);
});
});
1 change: 1 addition & 0 deletions cypress/support/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ declare global {
setupOwner(payload: SetupPayload): void;
skipSetup(): void;
resetAll(): void;
paste(pastePayload: string): void,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/editor-ui/src/mixins/copyPaste.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const copyPaste = Vue.extend({
hiddenInput.setAttribute('type', 'text');
hiddenInput.setAttribute('id', 'hidden-input-copy-paste');
hiddenInput.setAttribute('class', 'hidden-copy-paste');
hiddenInput.setAttribute('data-test-id', 'hidden-copy-paste');
this.hiddenInput = hiddenInput;

document.body.append(hiddenInput);
Expand Down
1 change: 1 addition & 0 deletions packages/editor-ui/src/views/NodeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<div
class="node-view-root"
id="node-view-root"
data-test-id="node-view-root"
@dragover="onDragOver"
@drop="onDrop"
>
Expand Down

0 comments on commit e07e32f

Please sign in to comment.