mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
feat(editor): Add Python to Code actions (#18668)
This commit is contained in:
@@ -9,6 +9,7 @@ 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 SET_NODE_NAME = 'Set';
|
||||
export const EDIT_FIELDS_SET_NODE_NAME = 'Edit Fields (Set)';
|
||||
export const LOOP_OVER_ITEMS_NODE_NAME = 'Loop Over Items';
|
||||
|
||||
@@ -473,4 +473,9 @@ export class CanvasPage extends BasePage {
|
||||
|
||||
await this.page.goto('/workflow/new');
|
||||
}
|
||||
|
||||
async addNodeWithSubItem(searchText: string, subItemText: string): Promise<void> {
|
||||
await this.addNode(searchText);
|
||||
await this.nodeCreatorSubItem(subItemText).click();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { MANUAL_TRIGGER_NODE_NAME, MANUAL_TRIGGER_NODE_DISPLAY_NAME } from '../../config/constants';
|
||||
import {
|
||||
MANUAL_TRIGGER_NODE_NAME,
|
||||
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
|
||||
CODE_NODE_NAME,
|
||||
CODE_NODE_DISPLAY_NAME,
|
||||
} from '../../config/constants';
|
||||
import { test, expect } from '../../fixtures/base';
|
||||
|
||||
test.describe('Canvas Node Actions', () => {
|
||||
@@ -52,8 +57,9 @@ test.describe('Canvas Node Actions', () => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
|
||||
await n8n.canvas.clickNodePlusEndpoint(MANUAL_TRIGGER_NODE_DISPLAY_NAME);
|
||||
await n8n.canvas.fillNodeCreatorSearchBar('Code');
|
||||
await n8n.canvas.fillNodeCreatorSearchBar(CODE_NODE_NAME);
|
||||
await n8n.page.keyboard.press('Enter');
|
||||
await n8n.canvas.nodeCreatorSubItem(CODE_NODE_DISPLAY_NAME).click();
|
||||
await n8n.page.keyboard.press('Escape');
|
||||
|
||||
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(2);
|
||||
@@ -63,7 +69,11 @@ test.describe('Canvas Node Actions', () => {
|
||||
test('should add disconnected node when nothing selected', async ({ n8n }) => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.deselectAll();
|
||||
await n8n.canvas.addNode('Code', { closeNDV: true });
|
||||
await n8n.canvas.clickNodeCreatorPlusButton();
|
||||
await n8n.canvas.fillNodeCreatorSearchBar(CODE_NODE_NAME);
|
||||
await n8n.page.keyboard.press('Enter');
|
||||
await n8n.canvas.nodeCreatorSubItem(CODE_NODE_DISPLAY_NAME).click();
|
||||
await n8n.page.keyboard.press('Escape');
|
||||
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(2);
|
||||
await expect(n8n.canvas.nodeConnections()).toHaveCount(0);
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
|
||||
CODE_NODE_NAME,
|
||||
HTTP_REQUEST_NODE_NAME,
|
||||
CODE_NODE_DISPLAY_NAME,
|
||||
} from '../../config/constants';
|
||||
import { test, expect } from '../../fixtures/base';
|
||||
|
||||
@@ -22,6 +23,7 @@ test.describe('Canvas Actions', () => {
|
||||
await n8n.canvas.clickNodePlusEndpoint(MANUAL_TRIGGER_NODE_DISPLAY_NAME);
|
||||
await n8n.canvas.fillNodeCreatorSearchBar(CODE_NODE_NAME);
|
||||
await n8n.page.keyboard.press('Enter');
|
||||
await n8n.canvas.nodeCreatorSubItem(CODE_NODE_DISPLAY_NAME).click();
|
||||
await n8n.page.keyboard.press('Escape');
|
||||
|
||||
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(2);
|
||||
@@ -32,12 +34,10 @@ test.describe('Canvas Actions', () => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.clickNodePlusEndpoint(MANUAL_TRIGGER_NODE_DISPLAY_NAME);
|
||||
await n8n.canvas.fillNodeCreatorSearchBar(CODE_NODE_NAME);
|
||||
|
||||
const sourceElement = n8n.canvas
|
||||
.nodeCreatorNodeItems()
|
||||
.filter({ hasText: CODE_NODE_NAME })
|
||||
.first();
|
||||
await sourceElement.dragTo(n8n.canvas.canvasPane(), { targetPosition: { x: 100, y: 100 } });
|
||||
await n8n.page.keyboard.press('Enter');
|
||||
await n8n.canvas
|
||||
.nodeCreatorSubItem(CODE_NODE_DISPLAY_NAME)
|
||||
.dragTo(n8n.canvas.canvasPane(), { targetPosition: { x: 100, y: 100 } });
|
||||
|
||||
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(2);
|
||||
await expect(n8n.canvas.nodeConnections()).toHaveCount(1);
|
||||
@@ -61,7 +61,7 @@ test.describe('Canvas Actions', () => {
|
||||
test('should add disconnected node if nothing is selected', async ({ n8n }) => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.deselectAll();
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { closeNDV: true });
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { action: CODE_NODE_DISPLAY_NAME, closeNDV: true });
|
||||
|
||||
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(2);
|
||||
await expect(n8n.canvas.nodeConnections()).toHaveCount(0);
|
||||
@@ -70,14 +70,14 @@ test.describe('Canvas Actions', () => {
|
||||
test('should add node between two connected nodes', async ({ n8n }) => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.nodeByName(MANUAL_TRIGGER_NODE_DISPLAY_NAME).click();
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { closeNDV: true });
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { action: CODE_NODE_DISPLAY_NAME, closeNDV: true });
|
||||
|
||||
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(2);
|
||||
await expect(n8n.canvas.nodeConnections()).toHaveCount(1);
|
||||
|
||||
await n8n.canvas.addNodeBetweenNodes(
|
||||
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
|
||||
CODE_NODE_NAME,
|
||||
CODE_NODE_DISPLAY_NAME,
|
||||
HTTP_REQUEST_NODE_NAME,
|
||||
);
|
||||
|
||||
@@ -96,8 +96,11 @@ test.describe('Canvas Actions', () => {
|
||||
test('should delete connections by clicking on the delete button', async ({ n8n }) => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.nodeByName(MANUAL_TRIGGER_NODE_DISPLAY_NAME).click();
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { closeNDV: true });
|
||||
await n8n.canvas.deleteConnectionBetweenNodes(MANUAL_TRIGGER_NODE_DISPLAY_NAME, CODE_NODE_NAME);
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { action: CODE_NODE_DISPLAY_NAME, closeNDV: true });
|
||||
await n8n.canvas.deleteConnectionBetweenNodes(
|
||||
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
|
||||
CODE_NODE_DISPLAY_NAME,
|
||||
);
|
||||
|
||||
await expect(n8n.canvas.nodeConnections()).toHaveCount(0);
|
||||
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(2);
|
||||
@@ -116,9 +119,9 @@ test.describe('Canvas Actions', () => {
|
||||
|
||||
test('should disable and enable node', async ({ n8n }) => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { closeNDV: true });
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { action: CODE_NODE_DISPLAY_NAME, closeNDV: true });
|
||||
|
||||
const disableButton = n8n.canvas.nodeDisableButton(CODE_NODE_NAME);
|
||||
const disableButton = n8n.canvas.nodeDisableButton(CODE_NODE_DISPLAY_NAME);
|
||||
await disableButton.click();
|
||||
|
||||
await expect(n8n.canvas.disabledNodes()).toHaveCount(1);
|
||||
@@ -130,8 +133,8 @@ test.describe('Canvas Actions', () => {
|
||||
|
||||
test('should delete node', async ({ n8n }) => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { closeNDV: true });
|
||||
await n8n.canvas.deleteNodeByName(CODE_NODE_NAME);
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { action: CODE_NODE_DISPLAY_NAME, closeNDV: true });
|
||||
await n8n.canvas.deleteNodeByName(CODE_NODE_DISPLAY_NAME);
|
||||
|
||||
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(1);
|
||||
await expect(n8n.canvas.nodeByName(MANUAL_TRIGGER_NODE_DISPLAY_NAME)).toBeVisible();
|
||||
@@ -140,9 +143,9 @@ test.describe('Canvas Actions', () => {
|
||||
|
||||
test('should copy selected nodes', async ({ n8n }) => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { closeNDV: true });
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { action: CODE_NODE_DISPLAY_NAME, closeNDV: true });
|
||||
await n8n.canvasComposer.selectAllAndCopy();
|
||||
await n8n.canvas.nodeByName(CODE_NODE_NAME).click();
|
||||
await n8n.canvas.nodeByName(CODE_NODE_DISPLAY_NAME).click();
|
||||
await n8n.canvasComposer.copySelectedNodesWithToast();
|
||||
|
||||
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(2);
|
||||
@@ -150,7 +153,7 @@ test.describe('Canvas Actions', () => {
|
||||
|
||||
test('should select/deselect all nodes', async ({ n8n }) => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { closeNDV: true });
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { action: CODE_NODE_DISPLAY_NAME, closeNDV: true });
|
||||
await n8n.canvas.selectAll();
|
||||
|
||||
await expect(n8n.canvas.selectedNodes()).toHaveCount(2);
|
||||
@@ -162,7 +165,7 @@ test.describe('Canvas Actions', () => {
|
||||
test('should select nodes using arrow keys', async ({ n8n }) => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.nodeByName(MANUAL_TRIGGER_NODE_DISPLAY_NAME).click();
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { closeNDV: true });
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { action: CODE_NODE_DISPLAY_NAME, closeNDV: true });
|
||||
await n8n.canvas.getCanvasNodes().first().waitFor();
|
||||
await n8n.canvas.navigateNodesWithArrows('left');
|
||||
|
||||
@@ -177,7 +180,7 @@ test.describe('Canvas Actions', () => {
|
||||
test('should select nodes using shift and arrow keys', async ({ n8n }) => {
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.nodeByName(MANUAL_TRIGGER_NODE_DISPLAY_NAME).click();
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { closeNDV: true });
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME, { action: CODE_NODE_DISPLAY_NAME, closeNDV: true });
|
||||
await n8n.canvas.getCanvasNodes().first().waitFor();
|
||||
await n8n.canvas.extendSelectionWithArrows('left');
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import { CODE_NODE_NAME, MANUAL_TRIGGER_NODE_NAME } from '../../config/constants';
|
||||
import {
|
||||
CODE_NODE_DISPLAY_NAME,
|
||||
CODE_NODE_NAME,
|
||||
MANUAL_TRIGGER_NODE_NAME,
|
||||
} from '../../config/constants';
|
||||
import { test, expect } from '../../fixtures/base';
|
||||
|
||||
test.describe('Code node', () => {
|
||||
@@ -9,7 +13,7 @@ test.describe('Code node', () => {
|
||||
await n8n.goHome();
|
||||
await n8n.workflows.clickAddWorkflowButton();
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME);
|
||||
await n8n.canvas.addNodeWithSubItem(CODE_NODE_NAME, CODE_NODE_DISPLAY_NAME);
|
||||
});
|
||||
|
||||
test('should show correct placeholders switching modes', async ({ n8n }) => {
|
||||
@@ -53,17 +57,17 @@ test.describe('Code node', () => {
|
||||
await n8n.ndv.getCodeEditor().fill("console.log('code node 1')");
|
||||
await n8n.ndv.close();
|
||||
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME);
|
||||
await n8n.canvas.addNodeWithSubItem(CODE_NODE_NAME, CODE_NODE_DISPLAY_NAME);
|
||||
|
||||
await n8n.ndv.getCodeEditor().fill("console.log('code node 2')");
|
||||
await n8n.ndv.close();
|
||||
|
||||
await n8n.canvas.openNode(CODE_NODE_NAME);
|
||||
await n8n.canvas.openNode(CODE_NODE_DISPLAY_NAME);
|
||||
|
||||
await n8n.ndv.clickFloatingNode('Code1');
|
||||
await n8n.ndv.clickFloatingNode(CODE_NODE_DISPLAY_NAME + '1');
|
||||
await expect(n8n.ndv.getCodeEditor()).toContainText("console.log('code node 2')");
|
||||
|
||||
await n8n.ndv.clickFloatingNode('Code');
|
||||
await n8n.ndv.clickFloatingNode(CODE_NODE_DISPLAY_NAME);
|
||||
await expect(n8n.ndv.getCodeEditor()).toContainText("console.log('code node 1')");
|
||||
});
|
||||
|
||||
@@ -112,7 +116,10 @@ return []
|
||||
await n8n.goHome();
|
||||
await n8n.workflows.clickAddWorkflowButton();
|
||||
await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME);
|
||||
await n8n.canvas.addNode(CODE_NODE_NAME);
|
||||
await n8n.canvas.clickNodeCreatorPlusButton();
|
||||
await n8n.canvas.fillNodeCreatorSearchBar(CODE_NODE_NAME);
|
||||
await n8n.page.keyboard.press('Enter');
|
||||
await n8n.canvas.clickNodeCreatorItemName(CODE_NODE_DISPLAY_NAME);
|
||||
});
|
||||
|
||||
test('tab should exist if experiment selected and be selectable', async ({ n8n }) => {
|
||||
|
||||
Reference in New Issue
Block a user