mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
chore: Add e2e tests for Subworkflow Conversion (no-changelog) (#16220)
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { getManualChatModal } from './modals/chat-modal';
|
import { getManualChatModal } from './modals/chat-modal';
|
||||||
import { clickGetBackToCanvas, getParameterInputByName } from './ndv';
|
import { clickGetBackToCanvas, getParameterInputByName } from './ndv';
|
||||||
import { ROUTES } from '../constants';
|
import { META_KEY, ROUTES } from '../constants';
|
||||||
import type { OpenContextMenuOptions } from '../types';
|
import type { OpenContextMenuOptions } from '../types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -364,3 +364,48 @@ export function openExecutions() {
|
|||||||
export function clickClearExecutionDataButton() {
|
export function clickClearExecutionDataButton() {
|
||||||
cy.getByTestId('clear-execution-data-button').click();
|
cy.getByTestId('clear-execution-data-button').click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo/Redo
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function hitComboShortcut(modifier: string, key: string) {
|
||||||
|
cy.get('body').wait(100).type(modifier, { delay: 100, release: false }).type(key);
|
||||||
|
}
|
||||||
|
export function hitUndo() {
|
||||||
|
hitComboShortcut(`{${META_KEY}}`, 'z');
|
||||||
|
}
|
||||||
|
export function hitRedo() {
|
||||||
|
cy.get('body').type(`{${META_KEY}+shift+z}`);
|
||||||
|
}
|
||||||
|
export function hitSelectAll() {
|
||||||
|
hitComboShortcut(`{${META_KEY}}`, 'a');
|
||||||
|
}
|
||||||
|
export function hitDeleteAllNodes() {
|
||||||
|
hitSelectAll();
|
||||||
|
cy.get('body').type('{backspace}');
|
||||||
|
}
|
||||||
|
export function hitDisableNodeShortcut() {
|
||||||
|
cy.get('body').type('d');
|
||||||
|
}
|
||||||
|
export function hitCopy() {
|
||||||
|
hitComboShortcut(`{${META_KEY}}`, 'c');
|
||||||
|
}
|
||||||
|
export function hitPinNodeShortcut() {
|
||||||
|
cy.get('body').type('p');
|
||||||
|
}
|
||||||
|
export function hitSaveWorkflow() {
|
||||||
|
cy.get('body').type(`{${META_KEY}+s}`);
|
||||||
|
}
|
||||||
|
export function hitExecuteWorkflow() {
|
||||||
|
cy.get('body').type(`{${META_KEY}+enter}`);
|
||||||
|
}
|
||||||
|
export function hitDuplicateNode() {
|
||||||
|
cy.get('body').type(`{${META_KEY}+d}`);
|
||||||
|
}
|
||||||
|
export function hitAddSticky() {
|
||||||
|
cy.get('body').type('{shift+S}');
|
||||||
|
}
|
||||||
|
export function selectRight() {
|
||||||
|
cy.get('body').type('{shift+rightArrow}');
|
||||||
|
}
|
||||||
|
|||||||
80
cypress/e2e/51-subworkflow-extraction.ts
Normal file
80
cypress/e2e/51-subworkflow-extraction.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import {
|
||||||
|
clickContextMenuAction,
|
||||||
|
clickZoomToFit,
|
||||||
|
executeWorkflow,
|
||||||
|
getCanvasNodeByName,
|
||||||
|
getCanvasNodes,
|
||||||
|
hitUndo,
|
||||||
|
navigateToNewWorkflowPage,
|
||||||
|
openContextMenu,
|
||||||
|
pasteWorkflow,
|
||||||
|
saveWorkflowOnButtonClick,
|
||||||
|
selectRight,
|
||||||
|
} from '../composables/workflow';
|
||||||
|
import SubworkflowExtractionFixture from '../fixtures/Subworkflow-extraction-workflow.json';
|
||||||
|
import { clearAnyNotifications, successToast } from '../pages/notifications';
|
||||||
|
|
||||||
|
const EDIT_FIELDS_NAMES = [
|
||||||
|
'Edit Fields0',
|
||||||
|
'Edit Fields1',
|
||||||
|
'Edit Fields2',
|
||||||
|
'Edit Fields3',
|
||||||
|
'Edit Fields4',
|
||||||
|
'Edit Fields5',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
function selectNode(nodeName: string) {
|
||||||
|
getCanvasNodeByName(nodeName).click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function executeAndConfirmSuccess() {
|
||||||
|
executeWorkflow();
|
||||||
|
successToast().should('contain.text', 'Workflow executed successfully');
|
||||||
|
clearAnyNotifications();
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Subworkflow Extraction', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
navigateToNewWorkflowPage();
|
||||||
|
// this selects all nodes
|
||||||
|
pasteWorkflow(SubworkflowExtractionFixture);
|
||||||
|
saveWorkflowOnButtonClick();
|
||||||
|
getCanvasNodes().should('have.length', 7);
|
||||||
|
clickZoomToFit();
|
||||||
|
|
||||||
|
executeAndConfirmSuccess();
|
||||||
|
|
||||||
|
openContextMenu();
|
||||||
|
clickContextMenuAction('deselect_all');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('can extract a valid selection and still execute the workflow', () => {
|
||||||
|
it('should extract a node and succeed execution, and then undo and succeed executions', () => {
|
||||||
|
for (const name of EDIT_FIELDS_NAMES) {
|
||||||
|
selectNode(name);
|
||||||
|
openContextMenu(name);
|
||||||
|
clickContextMenuAction('extract_sub_workflow');
|
||||||
|
cy.getByTestId('submit-button').click();
|
||||||
|
|
||||||
|
executeAndConfirmSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const _ of EDIT_FIELDS_NAMES) {
|
||||||
|
hitUndo();
|
||||||
|
|
||||||
|
executeAndConfirmSuccess();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should extract all nodes besides trigger and succeed execution', () => {
|
||||||
|
selectNode(EDIT_FIELDS_NAMES[0]);
|
||||||
|
selectRight();
|
||||||
|
openContextMenu();
|
||||||
|
clickContextMenuAction('extract_sub_workflow');
|
||||||
|
|
||||||
|
cy.getByTestId('submit-button').click();
|
||||||
|
|
||||||
|
executeAndConfirmSuccess();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
231
cypress/fixtures/Subworkflow-extraction-workflow.json
Normal file
231
cypress/fixtures/Subworkflow-extraction-workflow.json
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"parameters": {},
|
||||||
|
"type": "n8n-nodes-base.manualTrigger",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [0, -5],
|
||||||
|
"id": "41b93a1d-ca68-49c1-b252-323e57f58ba9",
|
||||||
|
"name": "When clicking ‘Execute workflow’"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"assignments": {
|
||||||
|
"assignments": [
|
||||||
|
{
|
||||||
|
"id": "624c7310-e17a-4075-922f-3b57952e3dfa",
|
||||||
|
"name": "x",
|
||||||
|
"value": "={{ $json.x + 'a' }}",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [220, -5],
|
||||||
|
"id": "afd95339-62f5-4efd-bcaa-637cec90ab0f",
|
||||||
|
"name": "Edit Fields0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"assignments": {
|
||||||
|
"assignments": [
|
||||||
|
{
|
||||||
|
"id": "624c7310-e17a-4075-922f-3b57952e3dfa",
|
||||||
|
"name": "x",
|
||||||
|
"value": "={{ $json.x + 'a' + $('When clicking ‘Execute workflow’').item.json.x}}",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [440, 120],
|
||||||
|
"id": "c279107f-08c2-4be6-9016-d19215cfeb9e",
|
||||||
|
"name": "Edit Fields1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"assignments": {
|
||||||
|
"assignments": [
|
||||||
|
{
|
||||||
|
"id": "624c7310-e17a-4075-922f-3b57952e3dfa",
|
||||||
|
"name": "x",
|
||||||
|
"value": "={{ $json.x + 'a' + $('When clicking ‘Execute workflow’').first().json.x }}",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [440, -120],
|
||||||
|
"id": "1d4eb1a0-ad87-4d8b-87e6-c853f27aa8ad",
|
||||||
|
"name": "Edit Fields2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"assignments": {
|
||||||
|
"assignments": [
|
||||||
|
{
|
||||||
|
"id": "624c7310-e17a-4075-922f-3b57952e3dfa",
|
||||||
|
"name": "x",
|
||||||
|
"value": "={{ $json.x + 'a' + $('When clicking ‘Execute workflow’').last().json.x}}",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [440, -320],
|
||||||
|
"id": "b99d763e-cb4c-487f-8718-8b9a5f02c167",
|
||||||
|
"name": "Edit Fields3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"assignments": {
|
||||||
|
"assignments": [
|
||||||
|
{
|
||||||
|
"id": "624c7310-e17a-4075-922f-3b57952e3dfa",
|
||||||
|
"name": "x",
|
||||||
|
"value": "={{ $json.x + 'a' + $('When clicking ‘Execute workflow’').item.json.x}}",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [720, 0],
|
||||||
|
"id": "4244c039-51c3-415b-8b3d-06be5a90dc7a",
|
||||||
|
"name": "Edit Fields4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"assignments": {
|
||||||
|
"assignments": [
|
||||||
|
{
|
||||||
|
"id": "624c7310-e17a-4075-922f-3b57952e3dfa",
|
||||||
|
"name": "x",
|
||||||
|
"value": "={{ $json.x + 'a' + $('When clicking ‘Execute workflow’').item.json.x + $('Edit Fields0').item.json.x }}",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [960, 0],
|
||||||
|
"id": "2653bbfe-8f06-4029-9071-8faacfb73cd0",
|
||||||
|
"name": "Edit Fields5"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connections": {
|
||||||
|
"When clicking ‘Execute workflow’": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Edit Fields0",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Edit Fields0": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Edit Fields1",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"node": "Edit Fields2",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"node": "Edit Fields3",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"node": "Edit Fields4",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Edit Fields1": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Edit Fields4",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Edit Fields2": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Edit Fields4",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Edit Fields3": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Edit Fields4",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Edit Fields4": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Edit Fields5",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pinData": {
|
||||||
|
"When clicking ‘Execute workflow’": [
|
||||||
|
{
|
||||||
|
"x": "l"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": "m"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": "o"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"instanceId": "d30ee1956588565f63beb4b8b589790a4701843b47fcd9e8d6d5527fe47872c3"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,3 +24,19 @@ export const clearNotifications = () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Clears notifications without asserting their existence
|
||||||
|
export const clearAnyNotifications = () => {
|
||||||
|
const notificationSelector = '.el-notification:has(.el-notification--success)';
|
||||||
|
cy.get('body')
|
||||||
|
.should('have.length.gte', 0)
|
||||||
|
.then(($body) => {
|
||||||
|
if ($body.find(notificationSelector).length) {
|
||||||
|
cy.get(notificationSelector).each(($el) => {
|
||||||
|
if ($el.find('.el-notification__closeBtn').length) {
|
||||||
|
cy.wrap($el).find('.el-notification__closeBtn').click({ force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user