1
1
mirror of https://github.com/n8n-io/n8n.git synced 2024-09-11 13:15:28 +03:00

fix(editor): Skip disabled nodes when detecting workflow issues (#9610)

This commit is contained in:
Milorad FIlipović 2024-06-04 13:26:57 +02:00 committed by GitHub
parent 87faa58045
commit 245c63f216
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 73 additions and 41 deletions

View File

@ -6,6 +6,7 @@ import {
EDIT_FIELDS_SET_NODE_NAME,
INSTANCE_MEMBERS,
INSTANCE_OWNER,
NOTION_NODE_NAME,
} from '../constants';
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
import { WorkflowsPage as WorkflowsPageClass } from '../pages/workflows';
@ -53,6 +54,30 @@ describe('Workflow Actions', () => {
WorkflowPage.getters.isWorkflowActivated();
});
it('should not be be able to activate workflow when nodes have errors', () => {
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(NOTION_NODE_NAME);
WorkflowPage.actions.saveWorkflowOnButtonClick();
WorkflowPage.getters.successToast().should('exist');
WorkflowPage.actions.clickWorkflowActivator();
WorkflowPage.getters.errorToast().should('exist');
});
it('should be be able to activate workflow when nodes with errors are disabled', () => {
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(NOTION_NODE_NAME);
WorkflowPage.actions.saveWorkflowOnButtonClick();
WorkflowPage.getters.successToast().should('exist');
// First, try to activate the workflow with errors
WorkflowPage.actions.clickWorkflowActivator();
WorkflowPage.getters.errorToast().should('exist');
// Now, disable the node with errors
WorkflowPage.getters.canvasNodes().last().click();
WorkflowPage.actions.hitDisableNodeShortcut();
WorkflowPage.actions.activateWorkflow();
WorkflowPage.getters.isWorkflowActivated();
});
it('should save new workflow after renaming', () => {
WorkflowPage.actions.renameWorkflow(NEW_WORKFLOW_NAME);
WorkflowPage.getters.isWorkflowSaved();
@ -162,45 +187,47 @@ describe('Workflow Actions', () => {
it('should update workflow settings', () => {
cy.visit(WorkflowPages.url);
WorkflowPages.getters.workflowCards().then((cards) => {
const totalWorkflows = cards.length;
cy.intercept('GET', '/rest/workflows', (req) => {
req.on('response', (res) => {
const totalWorkflows = res.body.count ?? 0;
WorkflowPage.actions.visit();
// Open settings dialog
WorkflowPage.actions.saveWorkflowOnButtonClick();
WorkflowPage.getters.workflowMenu().should('be.visible');
WorkflowPage.getters.workflowMenu().click();
WorkflowPage.getters.workflowMenuItemSettings().should('be.visible');
WorkflowPage.getters.workflowMenuItemSettings().click();
// Change all settings
// totalWorkflows + 1 (current workflow) + 1 (no workflow option)
WorkflowPage.getters.workflowSettingsErrorWorkflowSelect().click();
getVisibleSelect()
.find('li')
.should('have.length', totalWorkflows + 2);
getVisibleSelect().find('li').last().click({ force: true });
WorkflowPage.getters.workflowSettingsTimezoneSelect().click();
getVisibleSelect().find('li').should('exist');
getVisibleSelect().find('li').eq(1).click({ force: true });
WorkflowPage.getters.workflowSettingsSaveFiledExecutionsSelect().click();
getVisibleSelect().find('li').should('have.length', 3);
getVisibleSelect().find('li').last().click({ force: true });
WorkflowPage.getters.workflowSettingsSaveSuccessExecutionsSelect().click();
getVisibleSelect().find('li').should('have.length', 3);
getVisibleSelect().find('li').last().click({ force: true });
WorkflowPage.getters.workflowSettingsSaveManualExecutionsSelect().click();
getVisibleSelect().find('li').should('have.length', 3);
getVisibleSelect().find('li').last().click({ force: true });
WorkflowPage.getters.workflowSettingsSaveExecutionProgressSelect().click();
getVisibleSelect().find('li').should('have.length', 3);
getVisibleSelect().find('li').last().click({ force: true });
WorkflowPage.getters.workflowSettingsTimeoutWorkflowSwitch().click();
WorkflowPage.getters.workflowSettingsTimeoutForm().find('input').first().type('1');
// Save settings
WorkflowPage.getters.workflowSettingsSaveButton().click();
WorkflowPage.getters.workflowSettingsModal().should('not.exist');
WorkflowPage.getters.successToast().should('exist');
});
WorkflowPage.actions.visit();
// Open settings dialog
WorkflowPage.actions.saveWorkflowOnButtonClick();
WorkflowPage.getters.workflowMenu().should('be.visible');
WorkflowPage.getters.workflowMenu().click();
WorkflowPage.getters.workflowMenuItemSettings().should('be.visible');
WorkflowPage.getters.workflowMenuItemSettings().click();
// Change all settings
// totalWorkflows + 1 (current workflow) + 1 (no workflow option)
WorkflowPage.getters.workflowSettingsErrorWorkflowSelect().click();
getVisibleSelect()
.find('li')
.should('have.length', totalWorkflows + 2);
getVisibleSelect().find('li').last().click({ force: true });
WorkflowPage.getters.workflowSettingsTimezoneSelect().click();
getVisibleSelect().find('li').should('exist');
getVisibleSelect().find('li').eq(1).click({ force: true });
WorkflowPage.getters.workflowSettingsSaveFiledExecutionsSelect().click();
getVisibleSelect().find('li').should('have.length', 3);
getVisibleSelect().find('li').last().click({ force: true });
WorkflowPage.getters.workflowSettingsSaveSuccessExecutionsSelect().click();
getVisibleSelect().find('li').should('have.length', 3);
getVisibleSelect().find('li').last().click({ force: true });
WorkflowPage.getters.workflowSettingsSaveManualExecutionsSelect().click();
getVisibleSelect().find('li').should('have.length', 3);
getVisibleSelect().find('li').last().click({ force: true });
WorkflowPage.getters.workflowSettingsSaveExecutionProgressSelect().click();
getVisibleSelect().find('li').should('have.length', 3);
getVisibleSelect().find('li').last().click({ force: true });
WorkflowPage.getters.workflowSettingsTimeoutWorkflowSwitch().click();
WorkflowPage.getters.workflowSettingsTimeoutForm().find('input').first().type('1');
// Save settings
WorkflowPage.getters.workflowSettingsSaveButton().click();
WorkflowPage.getters.workflowSettingsModal().should('not.exist');
WorkflowPage.getters.successToast().should('exist');
});
}).as('loadWorkflows');
});
it('should not be able to delete unsaved workflow', () => {

View File

@ -298,10 +298,13 @@ export class WorkflowPage extends BasePage {
this.getters.workflowNameInput().should('be.enabled');
this.getters.workflowNameInput().clear().type(name).type('{enter}');
},
activateWorkflow: () => {
cy.intercept('PATCH', '/rest/workflows/*').as('activateWorkflow');
clickWorkflowActivator: () => {
this.getters.activatorSwitch().find('input').first().should('be.enabled');
this.getters.activatorSwitch().click();
},
activateWorkflow: () => {
cy.intercept('PATCH', '/rest/workflows/*').as('activateWorkflow');
this.actions.clickWorkflowActivator();
cy.wait('@activateWorkflow');
cy.get('body').type('{esc}');
},

View File

@ -175,7 +175,9 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
const nodesIssuesExist = computed(() => {
for (const node of workflow.value.nodes) {
if (node.issues === undefined || Object.keys(node.issues).length === 0) {
const isNodeDisabled = node.disabled === true;
const noNodeIssues = node.issues === undefined || Object.keys(node.issues).length === 0;
if (isNodeDisabled || noNodeIssues) {
continue;
}