mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
test(editor): Enable adding nodes in between any two nodes on canvas in e2e tests (no-changelog) (#5393)
* ⚡ Adding source and target test data to connection HTML elements * ⚡ Using new action to add node on the connection * 🔥 Removing leftover log * 🔥 Removing leftover test action * 👌 Refactoring to address PR feedback
This commit is contained in:
committed by
GitHub
parent
7e2f2f7453
commit
d05203db30
@@ -38,7 +38,7 @@ describe('Undo/Redo', () => {
|
|||||||
it('should undo/redo adding node in the middle', () => {
|
it('should undo/redo adding node in the middle', () => {
|
||||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||||
WorkflowPage.actions.addNodeBetweenFirstTwoNodes(CODE_NODE_NAME);
|
WorkflowPage.actions.addNodeBetweenNodes(SCHEDULE_TRIGGER_NODE_NAME, CODE_NODE_NAME, SET_NODE_NAME)
|
||||||
WorkflowPage.actions.zoomToFit();
|
WorkflowPage.actions.zoomToFit();
|
||||||
WorkflowPage.actions.hitUndo();
|
WorkflowPage.actions.hitUndo();
|
||||||
WorkflowPage.getters.canvasNodes().should('have.have.length', 2);
|
WorkflowPage.getters.canvasNodes().should('have.have.length', 2);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
CODE_NODE_NAME,
|
CODE_NODE_NAME,
|
||||||
SCHEDULE_TRIGGER_NODE_NAME,
|
SCHEDULE_TRIGGER_NODE_NAME,
|
||||||
SET_NODE_NAME,
|
SET_NODE_NAME,
|
||||||
|
HTTP_REQUEST_NODE_NAME,
|
||||||
} from './../constants';
|
} from './../constants';
|
||||||
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
|
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
|
||||||
|
|
||||||
@@ -61,14 +62,16 @@ describe('Canvas Actions', () => {
|
|||||||
it('should add note between two connected nodes', () => {
|
it('should add note between two connected nodes', () => {
|
||||||
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
|
||||||
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
|
||||||
WorkflowPage.actions.addNodeBetweenFirstTwoNodes(SET_NODE_NAME);
|
WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME);
|
||||||
WorkflowPage.getters.canvasNodes().should('have.length', 3);
|
WorkflowPage.actions.zoomToFit();
|
||||||
WorkflowPage.getters.nodeConnections().should('have.length', 2);
|
WorkflowPage.actions.addNodeBetweenNodes(CODE_NODE_NAME, SET_NODE_NAME, HTTP_REQUEST_NODE_NAME);
|
||||||
|
WorkflowPage.getters.canvasNodes().should('have.length', 4);
|
||||||
|
WorkflowPage.getters.nodeConnections().should('have.length', 3);
|
||||||
// And last node should be pushed to the right
|
// And last node should be pushed to the right
|
||||||
WorkflowPage.getters
|
WorkflowPage.getters
|
||||||
.canvasNodes()
|
.canvasNodes()
|
||||||
.last()
|
.last()
|
||||||
.should('have.attr', 'style', 'left: 640px; top: 260px;');
|
.should('have.attr', 'style', 'left: 860px; top: 260px;');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete node using node action button', () => {
|
it('should delete node using node action button', () => {
|
||||||
|
|||||||
@@ -80,6 +80,10 @@ export class WorkflowPage extends BasePage {
|
|||||||
nodeCreatorItems: () => cy.getByTestId('item-iterator-item'),
|
nodeCreatorItems: () => cy.getByTestId('item-iterator-item'),
|
||||||
ndvParameters: () => cy.getByTestId('parameter-item'),
|
ndvParameters: () => cy.getByTestId('parameter-item'),
|
||||||
nodeCredentialsLabel: () => cy.getByTestId('credentials-label'),
|
nodeCredentialsLabel: () => cy.getByTestId('credentials-label'),
|
||||||
|
getConnectionBetweenNodes: (sourceNodeName: string, targetNodeName: string) =>
|
||||||
|
cy.get(`.jtk-connector[data-source-node="${sourceNodeName}"][data-target-node="${targetNodeName}"]`),
|
||||||
|
getConnectionActionsBetweenNodes: (sourceNodeName: string, targetNodeName: string) =>
|
||||||
|
cy.get(`.connection-actions[data-source-node="${sourceNodeName}"][data-target-node="${targetNodeName}"]`),
|
||||||
};
|
};
|
||||||
actions = {
|
actions = {
|
||||||
visit: () => {
|
visit: () => {
|
||||||
@@ -170,10 +174,14 @@ export class WorkflowPage extends BasePage {
|
|||||||
executeWorkflow: () => {
|
executeWorkflow: () => {
|
||||||
this.getters.executeWorkflowButton().click();
|
this.getters.executeWorkflowButton().click();
|
||||||
},
|
},
|
||||||
addNodeBetweenFirstTwoNodes: (nodeName: string) => {
|
addNodeBetweenNodes: (sourceNodeName: string, targetNodeName: string, newNodeName: string) => {
|
||||||
this.getters.nodeConnections().first().realHover();
|
this.getters.getConnectionBetweenNodes(sourceNodeName, targetNodeName).first().realHover();
|
||||||
cy.get('.connection-actions .add').first().click({ force: true });
|
this.getters.getConnectionActionsBetweenNodes(sourceNodeName, targetNodeName).find('.add').first().click({ force: true });
|
||||||
this.actions.addNodeToCanvas(nodeName, false);
|
this.actions.addNodeToCanvas(newNodeName, false);
|
||||||
|
},
|
||||||
|
deleteNodeBetweenNodes: (sourceNodeName: string, targetNodeName: string, newNodeName: string) => {
|
||||||
|
this.getters.getConnectionBetweenNodes(sourceNodeName, targetNodeName).first().realHover();
|
||||||
|
this.getters.getConnectionActionsBetweenNodes(sourceNodeName, targetNodeName).find('.delete').first().click({ force: true });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { isNumber } from '@/utils';
|
|||||||
import { NODE_OUTPUT_DEFAULT_KEY, STICKY_NODE_TYPE, QUICKSTART_NOTE_NAME } from '@/constants';
|
import { NODE_OUTPUT_DEFAULT_KEY, STICKY_NODE_TYPE, QUICKSTART_NOTE_NAME } from '@/constants';
|
||||||
import { EndpointStyle, IBounds, INodeUi, XYPosition } from '@/Interface';
|
import { EndpointStyle, IBounds, INodeUi, XYPosition } from '@/Interface';
|
||||||
import { ArrayAnchorSpec, ConnectorSpec, OverlaySpec, PaintStyle } from '@jsplumb/common';
|
import { ArrayAnchorSpec, ConnectorSpec, OverlaySpec, PaintStyle } from '@jsplumb/common';
|
||||||
import { Endpoint, Connection } from '@jsplumb/core';
|
import { Endpoint, Connection, ConnectionEstablishedParams } from '@jsplumb/core';
|
||||||
import { N8nConnector } from '@/plugins/connectors/N8nCustomConnector';
|
import { N8nConnector } from '@/plugins/connectors/N8nCustomConnector';
|
||||||
import { closestNumberDivisibleBy } from '@/utils';
|
import { closestNumberDivisibleBy } from '@/utils';
|
||||||
import {
|
import {
|
||||||
@@ -741,6 +741,21 @@ export const moveBackInputLabelPosition = (targetEndpoint: Endpoint) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const addConnectionTestData = (
|
||||||
|
source: HTMLElement,
|
||||||
|
target: HTMLElement,
|
||||||
|
el: HTMLElement | undefined,
|
||||||
|
) => {
|
||||||
|
// TODO: Only do this if running in test mode
|
||||||
|
const sourceNodeName = source.getAttribute('data-name')?.toString();
|
||||||
|
const targetNodeName = target.getAttribute('data-name')?.toString();
|
||||||
|
|
||||||
|
if (el && sourceNodeName && targetNodeName) {
|
||||||
|
el.setAttribute('data-source-node', sourceNodeName);
|
||||||
|
el.setAttribute('data-target-node', targetNodeName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const addConnectionActionsOverlay = (
|
export const addConnectionActionsOverlay = (
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
onDelete: Function,
|
onDelete: Function,
|
||||||
@@ -756,15 +771,13 @@ export const addConnectionActionsOverlay = (
|
|||||||
const deleteButton = document.createElement('button');
|
const deleteButton = document.createElement('button');
|
||||||
|
|
||||||
div.classList.add(OVERLAY_CONNECTION_ACTIONS_ID);
|
div.classList.add(OVERLAY_CONNECTION_ACTIONS_ID);
|
||||||
|
addConnectionTestData(component.source, component.target, div);
|
||||||
addButton.classList.add('add');
|
addButton.classList.add('add');
|
||||||
deleteButton.classList.add('delete');
|
deleteButton.classList.add('delete');
|
||||||
|
|
||||||
addButton.innerHTML = getIcon('plus');
|
addButton.innerHTML = getIcon('plus');
|
||||||
deleteButton.innerHTML = getIcon('trash');
|
deleteButton.innerHTML = getIcon('trash');
|
||||||
|
|
||||||
addButton.addEventListener('click', () => onAdd());
|
addButton.addEventListener('click', () => onAdd());
|
||||||
deleteButton.addEventListener('click', () => onDelete());
|
deleteButton.addEventListener('click', () => onDelete());
|
||||||
|
|
||||||
// We have to manually trigger connection mouse events because the overlay
|
// We have to manually trigger connection mouse events because the overlay
|
||||||
// is not part of the connection element
|
// is not part of the connection element
|
||||||
div.addEventListener('mouseout', () =>
|
div.addEventListener('mouseout', () =>
|
||||||
@@ -773,7 +786,6 @@ export const addConnectionActionsOverlay = (
|
|||||||
div.addEventListener('mouseover', () =>
|
div.addEventListener('mouseover', () =>
|
||||||
connection.instance.fire(EVENT_CONNECTION_MOUSEOVER, component),
|
connection.instance.fire(EVENT_CONNECTION_MOUSEOVER, component),
|
||||||
);
|
);
|
||||||
|
|
||||||
div.appendChild(addButton);
|
div.appendChild(addButton);
|
||||||
div.appendChild(deleteButton);
|
div.appendChild(deleteButton);
|
||||||
return div;
|
return div;
|
||||||
|
|||||||
@@ -2182,6 +2182,15 @@ export default mixins(
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
setTimeout(() => {
|
||||||
|
NodeViewUtils.addConnectionTestData(
|
||||||
|
info.source,
|
||||||
|
info.target,
|
||||||
|
'canvas' in info.connection.connector
|
||||||
|
? (info.connection.connector.canvas as HTMLElement)
|
||||||
|
: undefined,
|
||||||
|
);
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e); // eslint-disable-line no-console
|
console.error(e); // eslint-disable-line no-console
|
||||||
|
|||||||
Reference in New Issue
Block a user