mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 12:57:29 -08:00
fix(editor): Skip disabled nodes when detecting workflow issues (#9610)
This commit is contained in:
parent
87faa58045
commit
245c63f216
|
@ -6,6 +6,7 @@ import {
|
||||||
EDIT_FIELDS_SET_NODE_NAME,
|
EDIT_FIELDS_SET_NODE_NAME,
|
||||||
INSTANCE_MEMBERS,
|
INSTANCE_MEMBERS,
|
||||||
INSTANCE_OWNER,
|
INSTANCE_OWNER,
|
||||||
|
NOTION_NODE_NAME,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
|
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
|
||||||
import { WorkflowsPage as WorkflowsPageClass } from '../pages/workflows';
|
import { WorkflowsPage as WorkflowsPageClass } from '../pages/workflows';
|
||||||
|
@ -53,6 +54,30 @@ describe('Workflow Actions', () => {
|
||||||
WorkflowPage.getters.isWorkflowActivated();
|
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', () => {
|
it('should save new workflow after renaming', () => {
|
||||||
WorkflowPage.actions.renameWorkflow(NEW_WORKFLOW_NAME);
|
WorkflowPage.actions.renameWorkflow(NEW_WORKFLOW_NAME);
|
||||||
WorkflowPage.getters.isWorkflowSaved();
|
WorkflowPage.getters.isWorkflowSaved();
|
||||||
|
@ -162,45 +187,47 @@ describe('Workflow Actions', () => {
|
||||||
|
|
||||||
it('should update workflow settings', () => {
|
it('should update workflow settings', () => {
|
||||||
cy.visit(WorkflowPages.url);
|
cy.visit(WorkflowPages.url);
|
||||||
WorkflowPages.getters.workflowCards().then((cards) => {
|
cy.intercept('GET', '/rest/workflows', (req) => {
|
||||||
const totalWorkflows = cards.length;
|
req.on('response', (res) => {
|
||||||
|
const totalWorkflows = res.body.count ?? 0;
|
||||||
|
|
||||||
WorkflowPage.actions.visit();
|
WorkflowPage.actions.visit();
|
||||||
// Open settings dialog
|
// Open settings dialog
|
||||||
WorkflowPage.actions.saveWorkflowOnButtonClick();
|
WorkflowPage.actions.saveWorkflowOnButtonClick();
|
||||||
WorkflowPage.getters.workflowMenu().should('be.visible');
|
WorkflowPage.getters.workflowMenu().should('be.visible');
|
||||||
WorkflowPage.getters.workflowMenu().click();
|
WorkflowPage.getters.workflowMenu().click();
|
||||||
WorkflowPage.getters.workflowMenuItemSettings().should('be.visible');
|
WorkflowPage.getters.workflowMenuItemSettings().should('be.visible');
|
||||||
WorkflowPage.getters.workflowMenuItemSettings().click();
|
WorkflowPage.getters.workflowMenuItemSettings().click();
|
||||||
// Change all settings
|
// Change all settings
|
||||||
// totalWorkflows + 1 (current workflow) + 1 (no workflow option)
|
// totalWorkflows + 1 (current workflow) + 1 (no workflow option)
|
||||||
WorkflowPage.getters.workflowSettingsErrorWorkflowSelect().click();
|
WorkflowPage.getters.workflowSettingsErrorWorkflowSelect().click();
|
||||||
getVisibleSelect()
|
getVisibleSelect()
|
||||||
.find('li')
|
.find('li')
|
||||||
.should('have.length', totalWorkflows + 2);
|
.should('have.length', totalWorkflows + 2);
|
||||||
getVisibleSelect().find('li').last().click({ force: true });
|
getVisibleSelect().find('li').last().click({ force: true });
|
||||||
WorkflowPage.getters.workflowSettingsTimezoneSelect().click();
|
WorkflowPage.getters.workflowSettingsTimezoneSelect().click();
|
||||||
getVisibleSelect().find('li').should('exist');
|
getVisibleSelect().find('li').should('exist');
|
||||||
getVisibleSelect().find('li').eq(1).click({ force: true });
|
getVisibleSelect().find('li').eq(1).click({ force: true });
|
||||||
WorkflowPage.getters.workflowSettingsSaveFiledExecutionsSelect().click();
|
WorkflowPage.getters.workflowSettingsSaveFiledExecutionsSelect().click();
|
||||||
getVisibleSelect().find('li').should('have.length', 3);
|
getVisibleSelect().find('li').should('have.length', 3);
|
||||||
getVisibleSelect().find('li').last().click({ force: true });
|
getVisibleSelect().find('li').last().click({ force: true });
|
||||||
WorkflowPage.getters.workflowSettingsSaveSuccessExecutionsSelect().click();
|
WorkflowPage.getters.workflowSettingsSaveSuccessExecutionsSelect().click();
|
||||||
getVisibleSelect().find('li').should('have.length', 3);
|
getVisibleSelect().find('li').should('have.length', 3);
|
||||||
getVisibleSelect().find('li').last().click({ force: true });
|
getVisibleSelect().find('li').last().click({ force: true });
|
||||||
WorkflowPage.getters.workflowSettingsSaveManualExecutionsSelect().click();
|
WorkflowPage.getters.workflowSettingsSaveManualExecutionsSelect().click();
|
||||||
getVisibleSelect().find('li').should('have.length', 3);
|
getVisibleSelect().find('li').should('have.length', 3);
|
||||||
getVisibleSelect().find('li').last().click({ force: true });
|
getVisibleSelect().find('li').last().click({ force: true });
|
||||||
WorkflowPage.getters.workflowSettingsSaveExecutionProgressSelect().click();
|
WorkflowPage.getters.workflowSettingsSaveExecutionProgressSelect().click();
|
||||||
getVisibleSelect().find('li').should('have.length', 3);
|
getVisibleSelect().find('li').should('have.length', 3);
|
||||||
getVisibleSelect().find('li').last().click({ force: true });
|
getVisibleSelect().find('li').last().click({ force: true });
|
||||||
WorkflowPage.getters.workflowSettingsTimeoutWorkflowSwitch().click();
|
WorkflowPage.getters.workflowSettingsTimeoutWorkflowSwitch().click();
|
||||||
WorkflowPage.getters.workflowSettingsTimeoutForm().find('input').first().type('1');
|
WorkflowPage.getters.workflowSettingsTimeoutForm().find('input').first().type('1');
|
||||||
// Save settings
|
// Save settings
|
||||||
WorkflowPage.getters.workflowSettingsSaveButton().click();
|
WorkflowPage.getters.workflowSettingsSaveButton().click();
|
||||||
WorkflowPage.getters.workflowSettingsModal().should('not.exist');
|
WorkflowPage.getters.workflowSettingsModal().should('not.exist');
|
||||||
WorkflowPage.getters.successToast().should('exist');
|
WorkflowPage.getters.successToast().should('exist');
|
||||||
});
|
});
|
||||||
|
}).as('loadWorkflows');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be able to delete unsaved workflow', () => {
|
it('should not be able to delete unsaved workflow', () => {
|
||||||
|
|
|
@ -298,10 +298,13 @@ export class WorkflowPage extends BasePage {
|
||||||
this.getters.workflowNameInput().should('be.enabled');
|
this.getters.workflowNameInput().should('be.enabled');
|
||||||
this.getters.workflowNameInput().clear().type(name).type('{enter}');
|
this.getters.workflowNameInput().clear().type(name).type('{enter}');
|
||||||
},
|
},
|
||||||
activateWorkflow: () => {
|
clickWorkflowActivator: () => {
|
||||||
cy.intercept('PATCH', '/rest/workflows/*').as('activateWorkflow');
|
|
||||||
this.getters.activatorSwitch().find('input').first().should('be.enabled');
|
this.getters.activatorSwitch().find('input').first().should('be.enabled');
|
||||||
this.getters.activatorSwitch().click();
|
this.getters.activatorSwitch().click();
|
||||||
|
},
|
||||||
|
activateWorkflow: () => {
|
||||||
|
cy.intercept('PATCH', '/rest/workflows/*').as('activateWorkflow');
|
||||||
|
this.actions.clickWorkflowActivator();
|
||||||
cy.wait('@activateWorkflow');
|
cy.wait('@activateWorkflow');
|
||||||
cy.get('body').type('{esc}');
|
cy.get('body').type('{esc}');
|
||||||
},
|
},
|
||||||
|
|
|
@ -175,7 +175,9 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
|
||||||
|
|
||||||
const nodesIssuesExist = computed(() => {
|
const nodesIssuesExist = computed(() => {
|
||||||
for (const node of workflow.value.nodes) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue