mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 09:36:44 +00:00
feat(editor): Add Python to Code actions (#18668)
This commit is contained in:
@@ -40,6 +40,8 @@ export const MANUAL_CHAT_TRIGGER_NODE_NAME = 'Chat Trigger';
|
||||
export const CHAT_TRIGGER_NODE_DISPLAY_NAME = 'When chat message received';
|
||||
export const SCHEDULE_TRIGGER_NODE_NAME = 'Schedule Trigger';
|
||||
export const CODE_NODE_NAME = 'Code';
|
||||
export const CODE_NODE_DISPLAY_NAME = 'Code in JavaScript';
|
||||
export const CODE_NODE_ACTION = CODE_NODE_DISPLAY_NAME;
|
||||
export const SET_NODE_NAME = 'Set';
|
||||
export const EDIT_FIELDS_SET_NODE_NAME = 'Edit Fields';
|
||||
export const LOOP_OVER_ITEMS_NODE_NAME = 'Loop Over Items';
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { getCanvasNodes } from '../composables/workflow';
|
||||
import {
|
||||
SCHEDULE_TRIGGER_NODE_NAME,
|
||||
CODE_NODE_NAME,
|
||||
SET_NODE_NAME,
|
||||
MANUAL_TRIGGER_NODE_NAME,
|
||||
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
|
||||
CODE_NODE_DISPLAY_NAME,
|
||||
} from '../constants';
|
||||
import { NDV } from '../pages/ndv';
|
||||
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
|
||||
@@ -19,9 +19,9 @@ describe('Undo/Redo', () => {
|
||||
|
||||
it('should undo/redo deleting node using context menu', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.addCodeNodeToCanvas();
|
||||
WorkflowPage.actions.zoomToFit();
|
||||
WorkflowPage.actions.deleteNodeFromContextMenu(CODE_NODE_NAME, {
|
||||
WorkflowPage.actions.deleteNodeFromContextMenu(CODE_NODE_DISPLAY_NAME, {
|
||||
method: 'right-click',
|
||||
anchor: 'topLeft',
|
||||
});
|
||||
@@ -37,8 +37,8 @@ describe('Undo/Redo', () => {
|
||||
|
||||
it('should undo/redo deleting node using keyboard shortcut', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.getters.canvasNodeByName(CODE_NODE_NAME).click();
|
||||
WorkflowPage.actions.addCodeNodeToCanvas();
|
||||
WorkflowPage.getters.canvasNodeByName(CODE_NODE_DISPLAY_NAME).click();
|
||||
cy.get('body').type('{backspace}');
|
||||
WorkflowPage.getters.canvasNodes().should('have.have.length', 1);
|
||||
WorkflowPage.getters.nodeConnections().should('have.length', 0);
|
||||
@@ -52,9 +52,9 @@ describe('Undo/Redo', () => {
|
||||
|
||||
it('should undo/redo deleting node between two connected nodes', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.addCodeNodeToCanvas();
|
||||
WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME);
|
||||
WorkflowPage.getters.canvasNodeByName(CODE_NODE_NAME).click();
|
||||
WorkflowPage.getters.canvasNodeByName(CODE_NODE_DISPLAY_NAME).click();
|
||||
WorkflowPage.actions.zoomToFit();
|
||||
cy.get('body').type('{backspace}');
|
||||
WorkflowPage.getters.canvasNodes().should('have.have.length', 2);
|
||||
@@ -69,7 +69,7 @@ describe('Undo/Redo', () => {
|
||||
|
||||
it('should undo/redo deleting whole workflow', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.addCodeNodeToCanvas();
|
||||
cy.get('body').type('{esc}');
|
||||
cy.get('body').type('{esc}');
|
||||
WorkflowPage.actions.hitDeleteAllNodes();
|
||||
@@ -85,7 +85,7 @@ describe('Undo/Redo', () => {
|
||||
it('should undo/redo moving nodes', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.getters.canvasNodeByName(MANUAL_TRIGGER_NODE_DISPLAY_NAME).click();
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.addCodeNodeToCanvas();
|
||||
|
||||
WorkflowPage.actions.zoomToFit();
|
||||
|
||||
@@ -131,8 +131,8 @@ describe('Undo/Redo', () => {
|
||||
|
||||
it('should undo/redo deleting a connection using context menu', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.deleteNodeBetweenNodes(SCHEDULE_TRIGGER_NODE_NAME, CODE_NODE_NAME);
|
||||
WorkflowPage.actions.addCodeNodeToCanvas();
|
||||
WorkflowPage.actions.deleteNodeBetweenNodes(SCHEDULE_TRIGGER_NODE_NAME, CODE_NODE_DISPLAY_NAME);
|
||||
WorkflowPage.getters.nodeConnections().should('have.length', 0);
|
||||
WorkflowPage.actions.hitUndo();
|
||||
WorkflowPage.getters.nodeConnections().should('have.length', 1);
|
||||
@@ -142,8 +142,8 @@ describe('Undo/Redo', () => {
|
||||
|
||||
it('should undo/redo disabling a node using context menu', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.disableNode(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.addCodeNodeToCanvas();
|
||||
WorkflowPage.actions.disableNode(CODE_NODE_DISPLAY_NAME);
|
||||
WorkflowPage.getters.disabledNodes().should('have.length', 1);
|
||||
WorkflowPage.actions.hitUndo();
|
||||
WorkflowPage.getters.disabledNodes().should('have.length', 0);
|
||||
@@ -153,7 +153,7 @@ describe('Undo/Redo', () => {
|
||||
|
||||
it('should undo/redo disabling a node using keyboard shortcut', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.addCodeNodeToCanvas();
|
||||
WorkflowPage.getters.canvasNodes().last().click();
|
||||
WorkflowPage.actions.hitDisableNodeShortcut();
|
||||
WorkflowPage.getters.disabledNodes().should('have.length', 1);
|
||||
@@ -165,7 +165,7 @@ describe('Undo/Redo', () => {
|
||||
|
||||
it('should undo/redo disabling multiple nodes', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.addCodeNodeToCanvas();
|
||||
cy.get('body').type('{esc}');
|
||||
cy.get('body').type('{esc}');
|
||||
WorkflowPage.actions.hitSelectAll();
|
||||
@@ -179,8 +179,8 @@ describe('Undo/Redo', () => {
|
||||
|
||||
it('should undo/redo duplicating a node', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.duplicateNode(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.addCodeNodeToCanvas();
|
||||
WorkflowPage.actions.duplicateNode(CODE_NODE_DISPLAY_NAME);
|
||||
WorkflowPage.actions.hitUndo();
|
||||
WorkflowPage.getters.canvasNodes().should('have.length', 2);
|
||||
WorkflowPage.actions.hitRedo();
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
EDIT_FIELDS_SET_NODE_NAME,
|
||||
SWITCH_NODE_NAME,
|
||||
MERGE_NODE_NAME,
|
||||
CODE_NODE_DISPLAY_NAME,
|
||||
} from './../constants';
|
||||
import {
|
||||
clickContextMenuAction,
|
||||
@@ -165,7 +166,7 @@ describe('Canvas Node Manipulation and Navigation', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.zoomToFit();
|
||||
WorkflowPage.actions.deleteNodeFromContextMenu(CODE_NODE_NAME, {
|
||||
WorkflowPage.actions.deleteNodeFromContextMenu(CODE_NODE_DISPLAY_NAME, {
|
||||
method: 'right-click',
|
||||
anchor: 'topLeft',
|
||||
});
|
||||
@@ -176,7 +177,7 @@ describe('Canvas Node Manipulation and Navigation', () => {
|
||||
it('should delete node using keyboard shortcut', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.getters.canvasNodeByName(CODE_NODE_NAME).click();
|
||||
WorkflowPage.getters.canvasNodeByName(CODE_NODE_DISPLAY_NAME).click();
|
||||
cy.get('body').type('{backspace}');
|
||||
WorkflowPage.getters.canvasNodes().should('have.length', 1);
|
||||
WorkflowPage.getters.nodeConnections().should('have.length', 0);
|
||||
@@ -188,7 +189,7 @@ describe('Canvas Node Manipulation and Navigation', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME);
|
||||
WorkflowPage.getters.canvasNodes().should('have.length', 3);
|
||||
WorkflowPage.getters.nodeConnections().should('have.length', 2);
|
||||
WorkflowPage.getters.canvasNodeByName(CODE_NODE_NAME).click();
|
||||
WorkflowPage.getters.canvasNodeByName(CODE_NODE_DISPLAY_NAME).click();
|
||||
WorkflowPage.actions.zoomToFit();
|
||||
cy.get('body').type('{backspace}');
|
||||
WorkflowPage.getters.canvasNodes().should('have.length', 2);
|
||||
@@ -318,7 +319,7 @@ describe('Canvas Node Manipulation and Navigation', () => {
|
||||
WorkflowPage.actions.hitDisableNodeShortcut();
|
||||
WorkflowPage.getters.disabledNodes().should('have.length', 1);
|
||||
|
||||
WorkflowPage.actions.disableNode(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.disableNode(CODE_NODE_DISPLAY_NAME);
|
||||
WorkflowPage.getters.disabledNodes().should('have.length', 0);
|
||||
});
|
||||
|
||||
@@ -394,7 +395,7 @@ describe('Canvas Node Manipulation and Navigation', () => {
|
||||
WorkflowPage.actions.addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
|
||||
WorkflowPage.getters.canvasNodeByName(MANUAL_TRIGGER_NODE_DISPLAY_NAME).click();
|
||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.duplicateNode(CODE_NODE_NAME);
|
||||
WorkflowPage.actions.duplicateNode(CODE_NODE_DISPLAY_NAME);
|
||||
WorkflowPage.getters.canvasNodes().should('have.length', 3);
|
||||
WorkflowPage.getters.nodeConnections().should('have.length', 1);
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ describe('NDV', () => {
|
||||
});
|
||||
|
||||
it('should not push NDV header out with a lot of code in Code node editor', () => {
|
||||
workflowPage.actions.addInitialNodeToCanvas('Code', { keepNdvOpen: true });
|
||||
workflowPage.actions.addInitialCodeNodeToCanvas({ keepNdvOpen: true });
|
||||
ndv.getters.parameterInput('jsCode').get('.cm-content').type('{selectall}').type('{backspace}');
|
||||
cy.fixture('Dummy_javascript.txt').then((code) => {
|
||||
ndv.getters.parameterInput('jsCode').get('.cm-content').paste(code);
|
||||
@@ -400,7 +400,7 @@ describe('NDV', () => {
|
||||
|
||||
it('should allow editing code in fullscreen in the code editors', () => {
|
||||
// Code (JavaScript)
|
||||
workflowPage.actions.addInitialNodeToCanvas('Code', { keepNdvOpen: true });
|
||||
workflowPage.actions.addInitialCodeNodeToCanvas({ keepNdvOpen: true });
|
||||
ndv.actions.openCodeEditorFullscreen();
|
||||
|
||||
ndv.getters.codeEditorFullscreen().type('{selectall}').type('{backspace}').type('foo()');
|
||||
@@ -725,8 +725,7 @@ describe('NDV', () => {
|
||||
});
|
||||
|
||||
it('should properly show node execution indicator', () => {
|
||||
workflowPage.actions.addInitialNodeToCanvas('Code');
|
||||
workflowPage.actions.openNode('Code');
|
||||
workflowPage.actions.addInitialCodeNodeToCanvas();
|
||||
// Should not show run info before execution
|
||||
ndv.getters.nodeRunSuccessIndicator().should('not.exist');
|
||||
ndv.getters.nodeRunErrorIndicator().should('not.exist');
|
||||
@@ -737,8 +736,7 @@ describe('NDV', () => {
|
||||
});
|
||||
|
||||
it('should properly show node execution indicator for multiple nodes', () => {
|
||||
workflowPage.actions.addInitialNodeToCanvas('Code');
|
||||
workflowPage.actions.openNode('Code');
|
||||
workflowPage.actions.addInitialCodeNodeToCanvas();
|
||||
ndv.actions.typeIntoParameterInput('jsCode', 'testets');
|
||||
ndv.getters.backToCanvas().click();
|
||||
workflowPage.actions.executeWorkflow();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { BasePage } from './base';
|
||||
import { NodeCreator } from './features/node-creator';
|
||||
import { clickContextMenuAction, getCanvasPane, openContextMenu } from '../composables/workflow';
|
||||
import { META_KEY } from '../constants';
|
||||
import { CODE_NODE_ACTION, CODE_NODE_NAME, META_KEY } from '../constants';
|
||||
import type { OpenContextMenuOptions } from '../types';
|
||||
import { getVisibleSelect } from '../utils';
|
||||
import { getUniqueWorkflowName } from '../utils/workflowUtils';
|
||||
@@ -179,6 +179,12 @@ export class WorkflowPage extends BasePage {
|
||||
win.preventNodeViewBeforeUnload = preventNodeViewUnload;
|
||||
});
|
||||
},
|
||||
addInitialCodeNodeToCanvas(opts: { keepNdvOpen: boolean } = { keepNdvOpen: false }) {
|
||||
this.addInitialNodeToCanvas(CODE_NODE_NAME, {
|
||||
action: CODE_NODE_ACTION,
|
||||
keepNdvOpen: opts.keepNdvOpen,
|
||||
});
|
||||
},
|
||||
addInitialNodeToCanvas: (
|
||||
nodeDisplayName: string,
|
||||
opts?: { keepNdvOpen?: boolean; action?: string; isTrigger?: boolean },
|
||||
@@ -202,6 +208,9 @@ export class WorkflowPage extends BasePage {
|
||||
cy.get('body').type('{esc}');
|
||||
}
|
||||
},
|
||||
addCodeNodeToCanvas(plusButtonClick = true, preventNdvClose?: boolean) {
|
||||
this.addNodeToCanvas(CODE_NODE_NAME, plusButtonClick, preventNdvClose, CODE_NODE_ACTION);
|
||||
},
|
||||
addNodeToCanvas: (
|
||||
nodeDisplayName: string,
|
||||
plusButtonClick = true,
|
||||
|
||||
Reference in New Issue
Block a user