ci: Remove unused canvas v1 related code from e2e tests (#15704)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2025-05-26 17:32:02 +02:00
committed by GitHub
parent eca282d09c
commit e9dc66b3ff
22 changed files with 119 additions and 520 deletions

View File

@@ -30,10 +30,7 @@ export function getCanvas() {
}
export function getCanvasPane() {
return cy.ifCanvasVersion(
() => cy.getByTestId('node-view-background'),
() => getCanvas().find('.vue-flow__pane'),
);
return getCanvas().find('.vue-flow__pane');
}
export function getContextMenu() {
@@ -45,55 +42,30 @@ export function getContextMenuAction(action: string) {
}
export function getInputPlusHandle(nodeName: string) {
return cy.ifCanvasVersion(
() => cy.get(`.add-input-endpoint[data-endpoint-name="${nodeName}"]`),
() =>
cy.get(
`[data-test-id="canvas-node-input-handle"][data-node-name="${nodeName}"] [data-test-id="canvas-handle-plus"]`,
),
return cy.get(
`[data-test-id="canvas-node-input-handle"][data-node-name="${nodeName}"] [data-test-id="canvas-handle-plus"]`,
);
}
export function getInputPlusHandleByType(nodeName: string, endpointType: EndpointType) {
return cy.ifCanvasVersion(
() =>
cy.get(
`.add-input-endpoint[data-jtk-scope-${endpointType}][data-endpoint-name="${nodeName}"]`,
),
() =>
cy.get(
`[data-test-id="canvas-node-input-handle"][data-connection-type="${endpointType}"][data-node-name="${nodeName}"] [data-test-id="canvas-handle-plus"]`,
),
return cy.get(
`[data-test-id="canvas-node-input-handle"][data-connection-type="${endpointType}"][data-node-name="${nodeName}"] [data-test-id="canvas-handle-plus"]`,
);
}
export function getOutputHandle(nodeName: string) {
return cy.ifCanvasVersion(
() => cy.get(`.add-output-endpoint[data-endpoint-name="${nodeName}"]`),
() => cy.get(`[data-test-id="canvas-node-output-handle"][data-node-name="${nodeName}"]`),
);
return cy.get(`[data-test-id="canvas-node-output-handle"][data-node-name="${nodeName}"]`);
}
export function getOutputPlusHandle(nodeName: string) {
return cy.ifCanvasVersion(
() => cy.get(`.add-output-endpoint[data-endpoint-name="${nodeName}"]`),
() =>
cy.get(
`[data-test-id="canvas-node-output-handle"][data-node-name="${nodeName}"] [data-test-id="canvas-handle-plus"]`,
),
return cy.get(
`[data-test-id="canvas-node-output-handle"][data-node-name="${nodeName}"] [data-test-id="canvas-handle-plus"]`,
);
}
export function getOutputPlusHandleByType(nodeName: string, endpointType: EndpointType) {
return cy.ifCanvasVersion(
() =>
cy.get(
`.add-output-endpoint[data-jtk-scope-${endpointType}][data-endpoint-name="${nodeName}"]`,
),
() =>
cy.get(
`[data-test-id="canvas-node-output-handle"][data-connection-type="${endpointType}"][data-node-name="${nodeName}"] [data-test-id="canvas-handle-plus"]`,
),
return cy.get(
`[data-test-id="canvas-node-output-handle"][data-connection-type="${endpointType}"][data-node-name="${nodeName}"] [data-test-id="canvas-handle-plus"]`,
);
}
@@ -114,10 +86,7 @@ export function getNodes() {
}
export function getNodeByName(name: string) {
return cy.ifCanvasVersion(
() => cy.getByTestId('canvas-node').filter(`[data-name="${name}"]`).eq(0),
() => cy.getByTestId('canvas-node').filter(`[data-node-name="${name}"]`).eq(0),
);
return cy.getByTestId('canvas-node').filter(`[data-node-name="${name}"]`).eq(0);
}
export function getNodesWithSpinner() {
@@ -133,10 +102,7 @@ export function getWaitingNodes() {
}
export function getNodeRenderedTypeByName(name: string) {
return cy.ifCanvasVersion(
() => getNodeByName(name),
() => getNodeByName(name).find('[data-canvas-node-render-type]'),
);
return getNodeByName(name).find('[data-canvas-node-render-type]');
}
export function getWorkflowHistoryCloseButton() {
@@ -150,18 +116,10 @@ export function disableNode(name: string) {
}
export function getConnectionBySourceAndTarget(source: string, target: string) {
return cy.ifCanvasVersion(
() =>
cy
.get('.jtk-connector')
.filter(`[data-source-node="${source}"][data-target-node="${target}"]`)
.eq(0),
() =>
cy
.getByTestId('edge')
.filter(`[data-source-node-name="${source}"][data-target-node-name="${target}"]`)
.eq(0),
);
return cy
.getByTestId('edge')
.filter(`[data-source-node-name="${source}"][data-target-node-name="${target}"]`)
.eq(0);
}
export function getConnectionLabelBySourceAndTarget(source: string, target: string) {
@@ -280,18 +238,11 @@ export function addSupplementalNodeToParent(
) {
connectNodeToParent(nodeName, endpointType, parentNodeName, exactMatch);
cy.ifCanvasVersion(
() => {
getConnectionBySourceAndTarget(parentNodeName, nodeName).should('exist');
},
() => {
if (endpointType === 'main') {
getConnectionBySourceAndTarget(parentNodeName, nodeName).should('exist');
} else {
getConnectionBySourceAndTarget(nodeName, parentNodeName).should('exist');
}
},
);
if (endpointType === 'main') {
getConnectionBySourceAndTarget(parentNodeName, nodeName).should('exist');
} else {
getConnectionBySourceAndTarget(nodeName, parentNodeName).should('exist');
}
}
export function addLanguageModelNodeToParent(
@@ -382,12 +333,7 @@ export function openContextMenu(
target.find('[data-test-id="overflow-node-button"]').click({ force: true });
}
cy.ifCanvasVersion(
() => {},
() => {
getContextMenu().should('be.visible');
},
);
getContextMenu().should('be.visible');
}
export function clickContextMenuAction(action: string) {

View File

@@ -94,19 +94,10 @@ describe('Undo/Redo', () => {
.then(($node) => {
const { x: x1, y: y1 } = $node[0].getBoundingClientRect();
cy.ifCanvasVersion(
() => {
cy.drag('[data-test-id="canvas-node"].jtk-drag-selected', [50, 150], {
clickToFinish: true,
});
},
() => {
cy.drag(getCanvasNodes().last(), [50, 150], {
realMouse: true,
abs: true,
});
},
);
cy.drag(getCanvasNodes().last(), [50, 150], {
realMouse: true,
abs: true,
});
getCanvasNodes()
.last()

View File

@@ -184,21 +184,11 @@ describe('Canvas Actions', () => {
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
cy.wait(500);
cy.get('body').type('{leftArrow}');
const selectedCanvasNodes = () =>
cy.ifCanvasVersion(
() => WorkflowPage.getters.canvasNodes(),
() => WorkflowPage.getters.canvasNodes().parent(),
);
const selectedCanvasNodes = () => WorkflowPage.getters.canvasNodes().parent();
cy.ifCanvasVersion(
() => selectedCanvasNodes().first().should('have.class', 'jtk-drag-selected'),
() => selectedCanvasNodes().first().should('have.class', 'selected'),
);
selectedCanvasNodes().first().should('have.class', 'selected');
cy.get('body').type('{rightArrow}');
cy.ifCanvasVersion(
() => selectedCanvasNodes().last().should('have.class', 'jtk-drag-selected'),
() => selectedCanvasNodes().last().should('have.class', 'selected'),
);
selectedCanvasNodes().last().should('have.class', 'selected');
});
it('should select nodes using shift and arrow keys', () => {

View File

@@ -48,46 +48,20 @@ describe('Canvas Node Manipulation and Navigation', () => {
NDVDialog.actions.close();
for (let i = 0; i < desiredOutputs; i++) {
cy.ifCanvasVersion(
() => {
WorkflowPage.getters
.canvasNodePlusEndpointByName(SWITCH_NODE_NAME, i)
.click({ force: true });
},
() => {
getOutputPlusHandle(SWITCH_NODE_NAME).eq(0).click();
},
);
getOutputPlusHandle(SWITCH_NODE_NAME).eq(0).click();
WorkflowPage.getters.nodeCreatorSearchBar().should('be.visible');
WorkflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, false);
WorkflowPage.actions.zoomToFit();
}
WorkflowPage.getters.nodeViewBackground().click({ force: true });
cy.ifCanvasVersion(
() => {
WorkflowPage.getters.canvasNodePlusEndpointByName(`${EDIT_FIELDS_SET_NODE_NAME}3`).click();
},
() => {
getOutputPlusHandle(`${EDIT_FIELDS_SET_NODE_NAME}3`).click();
},
);
getOutputPlusHandle(`${EDIT_FIELDS_SET_NODE_NAME}3`).click();
WorkflowPage.actions.addNodeToCanvas(SWITCH_NODE_NAME, false);
WorkflowPage.actions.saveWorkflowOnButtonClick();
cy.reload();
cy.waitForLoad();
// Make sure outputless switch was connected correctly
cy.ifCanvasVersion(
() => {
WorkflowPage.getters
.getConnectionBetweenNodes(`${EDIT_FIELDS_SET_NODE_NAME}3`, `${SWITCH_NODE_NAME}1`)
.should('exist');
},
() => {
getConnectionBySourceAndTarget(
`${EDIT_FIELDS_SET_NODE_NAME}3`,
`${SWITCH_NODE_NAME}1`,
).should('exist');
},
// Make sure output-less switch was connected correctly
getConnectionBySourceAndTarget(`${EDIT_FIELDS_SET_NODE_NAME}3`, `${SWITCH_NODE_NAME}1`).should(
'exist',
);
// Make sure all connections are there after reload
for (let i = 0; i < desiredOutputs; i++) {
@@ -116,27 +90,13 @@ describe('Canvas Node Manipulation and Navigation', () => {
);
// Connect Set1 and Set2 to merge
cy.ifCanvasVersion(
() => {
cy.draganddrop(
WorkflowPage.getters.getEndpointSelector('plus', EDIT_FIELDS_SET_NODE_NAME),
WorkflowPage.getters.getEndpointSelector('input', MERGE_NODE_NAME, 0),
);
cy.draganddrop(
WorkflowPage.getters.getEndpointSelector('plus', `${EDIT_FIELDS_SET_NODE_NAME}1`),
WorkflowPage.getters.getEndpointSelector('input', MERGE_NODE_NAME, 1),
);
},
() => {
cy.draganddrop(
WorkflowPage.getters.getEndpointSelector('output', EDIT_FIELDS_SET_NODE_NAME),
WorkflowPage.getters.getEndpointSelector('input', MERGE_NODE_NAME, 0),
);
cy.draganddrop(
WorkflowPage.getters.getEndpointSelector('output', `${EDIT_FIELDS_SET_NODE_NAME}1`),
WorkflowPage.getters.getEndpointSelector('input', MERGE_NODE_NAME, 1),
);
},
cy.draganddrop(
WorkflowPage.getters.getEndpointSelector('output', EDIT_FIELDS_SET_NODE_NAME),
WorkflowPage.getters.getEndpointSelector('input', MERGE_NODE_NAME, 0),
);
cy.draganddrop(
WorkflowPage.getters.getEndpointSelector('output', `${EDIT_FIELDS_SET_NODE_NAME}1`),
WorkflowPage.getters.getEndpointSelector('input', MERGE_NODE_NAME, 1),
);
const checkConnections = () => {
@@ -174,13 +134,9 @@ describe('Canvas Node Manipulation and Navigation', () => {
WorkflowPage.getters.stopExecutionButton().should('not.exist');
// If the merged set nodes are connected and executed correctly, there should be 2 items in the output of merge node
cy.ifCanvasVersion(
() => cy.get('[data-label="2 items"]').should('be.visible'),
() =>
getConnectionLabelBySourceAndTarget(`${EDIT_FIELDS_SET_NODE_NAME}1`, MERGE_NODE_NAME)
.contains('2 items')
.should('be.visible'),
);
getConnectionLabelBySourceAndTarget(`${EDIT_FIELDS_SET_NODE_NAME}1`, MERGE_NODE_NAME)
.contains('2 items')
.should('be.visible');
});
it('should add nodes and check execution success', () => {
@@ -192,45 +148,17 @@ describe('Canvas Node Manipulation and Navigation', () => {
WorkflowPage.actions.zoomToFit();
WorkflowPage.actions.executeWorkflow();
cy.ifCanvasVersion(
() => cy.get('.jtk-connector.success').should('have.length', 3),
() => cy.get('[data-edge-status=success]').should('have.length', 3),
);
cy.ifCanvasVersion(
() => cy.get('.data-count').should('have.length', 4),
() => cy.getByTestId('canvas-node-status-success').should('have.length', 4),
);
cy.ifCanvasVersion(
() => cy.get('.plus-draggable-endpoint').should('have.class', 'ep-success'),
() =>
cy
.getByTestId('canvas-handle-plus-wrapper')
.should('have.attr', 'data-plus-type', 'success'),
);
cy.get('[data-edge-status=success]').should('have.length', 3);
cy.getByTestId('canvas-node-status-success').should('have.length', 4);
cy.getByTestId('canvas-handle-plus-wrapper').should('have.attr', 'data-plus-type', 'success');
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
WorkflowPage.actions.zoomToFit();
cy.ifCanvasVersion(
() =>
cy
.get('.plus-draggable-endpoint')
.filter(':visible')
.should('not.have.class', 'ep-success'),
() =>
cy.getByTestId('canvas-handle-plus').should('not.have.attr', 'data-plus-type', 'success'),
);
cy.getByTestId('canvas-handle-plus').should('not.have.attr', 'data-plus-type', 'success');
cy.ifCanvasVersion(
() => cy.get('.jtk-connector.success').should('have.length', 3),
// The new version of the canvas correctly shows executed data being passed to the input of the next node
() => cy.get('[data-edge-status=success]').should('have.length', 4),
);
cy.ifCanvasVersion(
() => cy.get('.data-count').should('have.length', 4),
() => cy.getByTestId('canvas-node-status-success').should('have.length', 4),
);
cy.get('[data-edge-status=success]').should('have.length', 4);
cy.getByTestId('canvas-node-status-success').should('have.length', 4);
});
it('should delete node using context menu', () => {
@@ -311,19 +239,10 @@ describe('Canvas Node Manipulation and Navigation', () => {
.then(($node) => {
const { x: x1, y: y1 } = $node[0].getBoundingClientRect();
cy.ifCanvasVersion(
() => {
cy.drag('[data-test-id="canvas-node"].jtk-drag-selected', [50, 150], {
clickToFinish: true,
});
},
() => {
cy.drag(getCanvasNodes().last(), [50, 150], {
realMouse: true,
abs: true,
});
},
);
cy.drag(getCanvasNodes().last(), [50, 150], {
realMouse: true,
abs: true,
});
getCanvasNodes()
.last()
@@ -336,11 +255,7 @@ describe('Canvas Node Manipulation and Navigation', () => {
});
describe('Canvas Zoom Functionality', () => {
const getContainer = () =>
cy.ifCanvasVersion(
() => WorkflowPage.getters.nodeView(),
() => WorkflowPage.getters.canvasViewport(),
);
const getContainer = () => WorkflowPage.getters.canvasViewport();
const checkZoomLevel = (expectedFactor: number) => {
return getContainer().should(($nodeView) => {
const newTransform = $nodeView.css('transform');

View File

@@ -9,7 +9,6 @@ import {
import { SCHEDULE_TRIGGER_NODE_NAME, EDIT_FIELDS_SET_NODE_NAME } from '../constants';
import { NDV, WorkflowExecutionsTab, WorkflowPage as WorkflowPageClass } from '../pages';
import { clearNotifications, errorToast, successToast } from '../pages/notifications';
import { isCanvasV2 } from '../utils/workflowUtils';
const workflowPage = new WorkflowPageClass();
const executionsTab = new WorkflowExecutionsTab();
@@ -127,15 +126,9 @@ describe('Execution', () => {
.within(() => cy.get('.fa-check'))
.should('exist');
if (isCanvasV2()) {
workflowPage.getters
.canvasNodeByName('Wait')
.within(() => cy.get('.fa-sync-alt').should('not.exist'));
} else {
workflowPage.getters
.canvasNodeByName('Wait')
.within(() => cy.get('.fa-sync-alt').should('not.be.visible'));
}
workflowPage.getters
.canvasNodeByName('Wait')
.within(() => cy.get('.fa-sync-alt').should('not.exist'));
workflowPage.getters
.canvasNodeByName('Set')

View File

@@ -13,9 +13,6 @@ describe('ADO-2270 Save button resets on webhook node open', () => {
ndv.actions.close();
cy.ifCanvasVersion(
() => cy.getByTestId('workflow-save-button').should('not.contain', 'Saved'),
() => cy.getByTestId('workflow-save-button').should('contain', 'Saved'),
);
cy.getByTestId('workflow-save-button').should('contain', 'Saved');
});
});

View File

@@ -1,3 +1,4 @@
import { overrideFeatureFlag } from '../composables/featureFlags';
import planData from '../fixtures/Plan_data_opt_in_trial.json';
import {
MainSidebar,
@@ -73,10 +74,7 @@ describe('Cloud', () => {
describe('Easy AI workflow experiment', () => {
it('should not show option to take you to the easy AI workflow if experiment is control', () => {
window.localStorage.setItem(
'N8N_EXPERIMENT_OVERRIDES',
JSON.stringify({ '026_easy_ai_workflow': 'control' }),
);
overrideFeatureFlag('026_easy_ai_workflow', 'control');
cy.visit(workflowsPage.url);
@@ -84,10 +82,7 @@ describe('Cloud', () => {
});
it('should show option to take you to the easy AI workflow if experiment is variant', () => {
window.localStorage.setItem(
'N8N_EXPERIMENT_OVERRIDES',
JSON.stringify({ '026_easy_ai_workflow': 'variant' }),
);
overrideFeatureFlag('026_easy_ai_workflow', 'variant');
cy.visit(workflowsPage.url);
@@ -95,10 +90,7 @@ describe('Cloud', () => {
});
it('should show default instructions if free AI credits experiment is control', () => {
window.localStorage.setItem(
'N8N_EXPERIMENT_OVERRIDES',
JSON.stringify({ '026_easy_ai_workflow': 'variant' }),
);
overrideFeatureFlag('026_easy_ai_workflow', 'variant');
cy.visit(workflowsPage.url);

View File

@@ -87,28 +87,14 @@ describe('Debug', () => {
confirmDialog.get('.btn--confirm').click();
cy.url().should('include', '/debug');
cy.ifCanvasVersion(
() => {
workflowPage.getters
.canvasNodes()
.first()
.should('have.descendants', '.node-pin-data-icon');
workflowPage.getters
.canvasNodes()
.not(':first')
.should('not.have.descendants', '.node-pin-data-icon');
},
() => {
workflowPage.getters
.canvasNodes()
.first()
.should('have.descendants', '[data-test-id="canvas-node-status-pinned"]');
workflowPage.getters
.canvasNodes()
.not(':first')
.should('not.have.descendants', '[data-test-id="canvas-node-status-pinned"]');
},
);
workflowPage.getters
.canvasNodes()
.first()
.should('have.descendants', '[data-test-id="canvas-node-status-pinned"]');
workflowPage.getters
.canvasNodes()
.not(':first')
.should('not.have.descendants', '[data-test-id="canvas-node-status-pinned"]');
cy.reload(true);
cy.wait(['@getExecution']);
@@ -131,18 +117,7 @@ describe('Debug', () => {
confirmDialog.get('.btn--confirm').click();
cy.url().should('include', '/debug');
cy.ifCanvasVersion(
() => {
workflowPage.getters.canvasNodes().last().find('.node-info-icon').should('be.empty');
},
() => {
workflowPage.getters
.canvasNodes()
.last()
.find('[class*="statusIcons"]')
.should('not.exist');
},
);
workflowPage.getters.canvasNodes().last().find('[class*="statusIcons"]').should('not.exist');
workflowPage.getters.canvasNodes().first().dblclick();
ndv.actions.unPinData();

View File

@@ -76,20 +76,10 @@ describe('Node Creator', () => {
nodeCreatorFeature.getters.canvasAddButton().click();
WorkflowPage.actions.addNodeToCanvas('Manual', false);
cy.ifCanvasVersion(
() => {
nodeCreatorFeature.getters.canvasAddButton().should('not.be.visible');
nodeCreatorFeature.getters.nodeCreator().should('not.exist');
// TODO: Replace once we have canvas feature utils
cy.get('div').contains('Add first step').should('be.hidden');
},
() => {
nodeCreatorFeature.getters.canvasAddButton().should('not.exist');
nodeCreatorFeature.getters.nodeCreator().should('not.exist');
// TODO: Replace once we have canvas feature utils
cy.get('div').contains('Add first step').should('not.exist');
},
);
nodeCreatorFeature.getters.canvasAddButton().should('not.exist');
nodeCreatorFeature.getters.nodeCreator().should('not.exist');
// TODO: Replace once we have canvas feature utils
cy.get('div').contains('Add first step').should('not.exist');
nodeCreatorFeature.actions.openNodeCreator();
nodeCreatorFeature.getters.nodeCreator().contains('What happens next?').should('be.visible');
@@ -356,14 +346,7 @@ describe('Node Creator', () => {
it('should correctly append a No Op node when Loop Over Items node is added (from connection)', () => {
WorkflowPage.actions.addNodeToCanvas('Manual');
cy.ifCanvasVersion(
() => {
cy.get('.plus-endpoint').click();
},
() => {
cy.getByTestId('canvas-handle-plus').click();
},
);
cy.getByTestId('canvas-handle-plus').click();
nodeCreatorFeature.getters.searchBar().find('input').type('Loop Over Items');
nodeCreatorFeature.getters.getCreatorItem('Loop Over Items').click();

View File

@@ -463,17 +463,10 @@ describe('NDV', () => {
return cy.get(`[data-node-placement=${position}]`);
}
// Correctly failing in V2 - due to floating navigation not updating the selected node
it('should traverse floating nodes with mouse', () => {
cy.createFixtureWorkflow('Floating_Nodes.json', 'Floating Nodes');
cy.ifCanvasVersion(
() => {},
() => {
// Needed in V2 as all nodes remain selected when clicking on a selected node
workflowPage.actions.deselectAll();
},
);
workflowPage.actions.deselectAll();
workflowPage.getters.canvasNodes().first().dblclick();
getFloatingNodeByPosition('inputMain').should('not.exist');
@@ -518,16 +511,9 @@ describe('NDV', () => {
.should('contain', MANUAL_TRIGGER_NODE_DISPLAY_NAME);
});
// Correctly failing in V2 - due to floating navigation not updating the selected node
it('should traverse floating nodes with keyboard', () => {
cy.createFixtureWorkflow('Floating_Nodes.json', 'Floating Nodes');
cy.ifCanvasVersion(
() => {},
() => {
// Needed in V2 as all nodes remain selected when clicking on a selected node
workflowPage.actions.deselectAll();
},
);
workflowPage.actions.deselectAll();
workflowPage.getters.canvasNodes().first().dblclick();
getFloatingNodeByPosition('inputMain').should('not.exist');
@@ -539,7 +525,6 @@ describe('NDV', () => {
getFloatingNodeByPosition('inputMain').should('exist');
getFloatingNodeByPosition('outputMain').should('exist');
ndv.actions.close();
// These two lines are broken in V2
workflowPage.getters.selectedNodes().should('have.length', 1);
workflowPage.getters
.selectedNodes()
@@ -567,7 +552,6 @@ describe('NDV', () => {
getFloatingNodeByPosition('inputSub').should('not.exist');
getFloatingNodeByPosition('outputSub').should('not.exist');
ndv.actions.close();
// These two lines are broken in V2
workflowPage.getters.selectedNodes().should('have.length', 1);
workflowPage.getters
.selectedNodes()
@@ -624,13 +608,7 @@ describe('NDV', () => {
it('should have the floating nodes in correct order', () => {
cy.createFixtureWorkflow('Floating_Nodes.json', 'Floating Nodes');
cy.ifCanvasVersion(
() => {},
() => {
// Needed in V2 as all nodes remain selected when clicking on a selected node
workflowPage.actions.deselectAll();
},
);
workflowPage.actions.deselectAll();
// The first merge node has the wires crossed, so `Edit Fields1` is first in the order of connected nodes
openNode('Merge');

View File

@@ -200,14 +200,7 @@ describe('Workflow Actions', () => {
WorkflowPage.getters.nodeConnections().should('have.length', 2);
// Check if all nodes have names
WorkflowPage.getters.canvasNodes().each((node) => {
cy.ifCanvasVersion(
() => {
cy.wrap(node).should('have.attr', 'data-name');
},
() => {
cy.wrap(node).should('have.attr', 'data-node-name');
},
);
cy.wrap(node).should('have.attr', 'data-node-name');
});
});
});
@@ -469,16 +462,7 @@ describe('Workflow Actions', () => {
// Clear the canvas
WorkflowPage.actions.hitDeleteAllNodes();
WorkflowPage.getters.canvasNodes().should('have.length', 0);
// Button should be disabled
cy.ifCanvasVersion(
() => {
WorkflowPage.getters.executeWorkflowButton().should('be.disabled');
},
() => {
// In new canvas, button does not exist when there are no nodes
WorkflowPage.getters.executeWorkflowButton().should('not.exist');
},
);
WorkflowPage.getters.executeWorkflowButton().should('not.exist');
// Keyboard shortcut should not work
WorkflowPage.actions.hitExecuteWorkflow();
successToast().should('not.exist');

View File

@@ -6,7 +6,6 @@
"cypress:install": "cypress install",
"test:e2e:ui": "scripts/run-e2e.js ui",
"test:e2e:dev": "scripts/run-e2e.js dev",
"test:e2e:dev:v1": "scripts/run-e2e.js dev:v1",
"test:e2e:all": "scripts/run-e2e.js all",
"test:flaky": "scripts/run-e2e.js debugFlaky",
"format": "biome format --write .",

View File

@@ -38,12 +38,7 @@ export class WorkflowExecutionsTab extends BasePage {
actions = {
toggleNodeEnabled: (nodeName: string) => {
cy.ifCanvasVersion(
() => {},
() => {
cy.get('body').click(); // Cancel selection if it exists
},
);
cy.get('body').click(); // Cancel selection if it exists
workflowPage.getters.canvasNodeByName(nodeName).click();
cy.get('body').type('d', { force: true });
},

View File

@@ -4,7 +4,7 @@ import { clickContextMenuAction, getCanvasPane, openContextMenu } from '../compo
import { META_KEY } from '../constants';
import type { OpenContextMenuOptions } from '../types';
import { getVisibleSelect } from '../utils';
import { getUniqueWorkflowName, isCanvasV2 } from '../utils/workflowUtils';
import { getUniqueWorkflowName } from '../utils/workflowUtils';
const nodeCreator = new NodeCreator();
@@ -49,18 +49,13 @@ export class WorkflowPage extends BasePage {
.should('have.length.greaterThan', 0)
.findChildByTestId('node-issues'),
getEndpointSelector: (type: 'input' | 'output' | 'plus', nodeName: string, index = 0) => {
if (isCanvasV2()) {
if (type === 'input') {
return `[data-test-id="canvas-node-input-handle"][data-node-name="${nodeName}"][data-index="${index}"]`;
}
if (type === 'output') {
return `[data-test-id="canvas-node-output-handle"][data-node-name="${nodeName}"][data-index="${index}"]`;
}
if (type === 'plus') {
return `[data-test-id="canvas-node-output-handle"][data-node-name="${nodeName}"][data-index="${index}"] [data-test-id="canvas-handle-plus"]`;
}
if (type === 'input') {
return `[data-test-id="canvas-node-input-handle"][data-node-name="${nodeName}"][data-index="${index}"]`;
}
return `[data-endpoint-name='${nodeName}'][data-endpoint-type='${type}'][data-input-index='${index}']`;
if (type === 'output') {
return `[data-test-id="canvas-node-output-handle"][data-node-name="${nodeName}"][data-index="${index}"]`;
}
return `[data-test-id="canvas-node-output-handle"][data-node-name="${nodeName}"][data-index="${index}"] [data-test-id="canvas-handle-plus"]`;
},
canvasNodeInputEndpointByName: (nodeName: string, index = 0) => {
return cy.get(this.getters.getEndpointSelector('input', nodeName, index));
@@ -69,15 +64,11 @@ export class WorkflowPage extends BasePage {
return cy.get(this.getters.getEndpointSelector('output', nodeName, index));
},
canvasNodePlusEndpointByName: (nodeName: string, index = 0) => {
return cy.ifCanvasVersion(
() => cy.get(this.getters.getEndpointSelector('plus', nodeName, index)),
() =>
cy
.get(
`[data-test-id="canvas-node-output-handle"][data-node-name="${nodeName}"] [data-test-id="canvas-handle-plus"]`,
)
.eq(index),
);
return cy
.get(
`[data-test-id="canvas-node-output-handle"][data-node-name="${nodeName}"] [data-test-id="canvas-handle-plus"]`,
)
.eq(index);
},
activatorSwitch: () => cy.getByTestId('workflow-activate-switch'),
workflowMenu: () => cy.getByTestId('workflow-menu'),
@@ -89,29 +80,13 @@ export class WorkflowPage extends BasePage {
expressionModalInput: () => cy.getByTestId('expression-modal-input').find('[role=textbox]'),
expressionModalOutput: () => cy.getByTestId('expression-modal-output'),
nodeViewRoot: () =>
cy.ifCanvasVersion(
() => cy.getByTestId('node-view-root'),
() => this.getters.nodeView(),
),
nodeViewRoot: () => this.getters.nodeView(),
copyPasteInput: () => cy.getByTestId('hidden-copy-paste'),
nodeConnections: () =>
cy.ifCanvasVersion(
() => cy.get('.jtk-connector'),
() => cy.getByTestId('edge'),
),
nodeConnections: () => cy.getByTestId('edge'),
zoomToFitButton: () => cy.getByTestId('zoom-to-fit'),
nodeEndpoints: () => cy.get('.jtk-endpoint-connected'),
disabledNodes: () =>
cy.ifCanvasVersion(
() => cy.get('.node-box.disabled'),
() => cy.get('[data-canvas-node-render-type][class*="disabled"]'),
),
selectedNodes: () =>
cy.ifCanvasVersion(
() => this.getters.canvasNodes().filter('.jtk-drag-selected'),
() => this.getters.canvasNodes().parent().filter('.selected'),
),
disabledNodes: () => cy.get('[data-canvas-node-render-type][class*="disabled"]'),
selectedNodes: () => this.getters.canvasNodes().parent().filter('.selected'),
// Workflow menu items
workflowMenuItemDuplicate: () => cy.getByTestId('workflow-menu-item-duplicate'),
workflowMenuItemDownload: () => cy.getByTestId('workflow-menu-item-download'),
@@ -144,21 +119,9 @@ export class WorkflowPage extends BasePage {
shareButton: () => cy.getByTestId('workflow-share-button'),
duplicateWorkflowModal: () => cy.getByTestId('duplicate-modal'),
nodeViewBackground: () =>
cy.ifCanvasVersion(
() => cy.getByTestId('node-view-background'),
() => cy.getByTestId('canvas'),
),
nodeView: () =>
cy.ifCanvasVersion(
() => cy.getByTestId('node-view'),
() => cy.get('[data-test-id="canvas-wrapper"]'),
),
canvasViewport: () =>
cy.ifCanvasVersion(
() => cy.getByTestId('node-view'),
() => cy.get('.vue-flow__transformationpane.vue-flow__container'),
),
nodeViewBackground: () => cy.getByTestId('canvas'),
nodeView: () => cy.get('[data-test-id="canvas-wrapper"]'),
canvasViewport: () => cy.get('.vue-flow__transformationpane.vue-flow__container'),
inlineExpressionEditorInput: () =>
cy.getByTestId('inline-expression-editor-input').find('[role=textbox]'),
inlineExpressionEditorOutput: () => cy.getByTestId('inline-expression-editor-output'),
@@ -180,26 +143,12 @@ export class WorkflowPage extends BasePage {
ndvParameters: () => cy.getByTestId('parameter-item'),
nodeCredentialsLabel: () => cy.getByTestId('credentials-label'),
getConnectionBetweenNodes: (sourceNodeName: string, targetNodeName: string) =>
cy.ifCanvasVersion(
() =>
cy.get(
`.jtk-connector[data-source-node="${sourceNodeName}"][data-target-node="${targetNodeName}"]`,
),
() =>
cy.get(
`[data-test-id="edge"][data-source-node-name="${sourceNodeName}"][data-target-node-name="${targetNodeName}"]`,
),
cy.get(
`[data-test-id="edge"][data-source-node-name="${sourceNodeName}"][data-target-node-name="${targetNodeName}"]`,
),
getConnectionActionsBetweenNodes: (sourceNodeName: string, targetNodeName: string) =>
cy.ifCanvasVersion(
() =>
cy.get(
`.connection-actions[data-source-node="${sourceNodeName}"][data-target-node="${targetNodeName}"]`,
),
() =>
cy.get(
`[data-test-id="edge-label"][data-source-node-name="${sourceNodeName}"][data-target-node-name="${targetNodeName}"] [data-test-id="canvas-edge-toolbar"]`,
),
cy.get(
`[data-test-id="edge-label"][data-source-node-name="${sourceNodeName}"][data-target-node-name="${targetNodeName}"] [data-test-id="canvas-edge-toolbar"]`,
),
addStickyButton: () => cy.getByTestId('add-sticky-button'),
stickies: () => cy.getByTestId('sticky'),
@@ -208,16 +157,10 @@ export class WorkflowPage extends BasePage {
colors: () => cy.getByTestId('color'),
contextMenuAction: (action: string) => cy.getByTestId(`context-menu-item-${action}`),
getNodeLeftPosition: (element: JQuery<HTMLElement>) => {
if (isCanvasV2()) {
return parseFloat(element.parent().css('transform').split(',')[4]);
}
return parseFloat(element.css('left'));
return parseFloat(element.parent().css('transform').split(',')[4]);
},
getNodeTopPosition: (element: JQuery<HTMLElement>) => {
if (isCanvasV2()) {
return parseFloat(element.parent().css('transform').split(',')[5]);
}
return parseFloat(element.css('top'));
return parseFloat(element.parent().css('transform').split(',')[5]);
},
inputURLImportWorkflowFromURL: () => cy.getByTestId('workflow-url-import-input'),
cancelActionImportWorkflowFromURL: () => cy.getByTestId('cancel-workflow-import-url-button'),
@@ -290,23 +233,7 @@ export class WorkflowPage extends BasePage {
nodeTypeName?: string,
{ method = 'right-click', anchor = 'center' }: OpenContextMenuOptions = {},
) => {
cy.ifCanvasVersion(
() => {
const target = nodeTypeName
? this.getters.canvasNodeByName(nodeTypeName)
: this.getters.nodeViewBackground();
if (method === 'right-click') {
target.rightclick(nodeTypeName ? anchor : 'topLeft', { force: true });
} else {
target.realHover();
target.find('[data-test-id="overflow-node-button"]').click({ force: true });
}
},
() => {
openContextMenu(nodeTypeName, { method, anchor });
},
);
openContextMenu(nodeTypeName, { method, anchor });
},
openNode: (nodeTypeName: string) => {
this.getters.canvasNodeByName(nodeTypeName).first().dblclick();
@@ -355,13 +282,7 @@ export class WorkflowPage extends BasePage {
clickContextMenuAction('select_all');
},
deselectAll: () => {
cy.ifCanvasVersion(
() => {
this.actions.openContextMenu();
clickContextMenuAction('deselect_all');
},
() => getCanvasPane().click('topLeft'),
);
getCanvasPane().click('topLeft');
},
openExpressionEditorModal: () => {
cy.contains('Expression').invoke('show').click();
@@ -500,10 +421,8 @@ export class WorkflowPage extends BasePage {
this.getters.getConnectionBetweenNodes(sourceNodeName, targetNodeName).first().realHover();
const connectionsBetweenNodes = () =>
this.getters.getConnectionActionsBetweenNodes(sourceNodeName, targetNodeName);
cy.ifCanvasVersion(
() => connectionsBetweenNodes().find('.add'),
() => connectionsBetweenNodes().get('[data-test-id="add-connection-button"]'),
)
connectionsBetweenNodes()
.get('[data-test-id="add-connection-button"]')
.first()
.click({ force: true });
@@ -513,10 +432,8 @@ export class WorkflowPage extends BasePage {
this.getters.getConnectionBetweenNodes(sourceNodeName, targetNodeName).first().realHover();
const connectionsBetweenNodes = () =>
this.getters.getConnectionActionsBetweenNodes(sourceNodeName, targetNodeName);
cy.ifCanvasVersion(
() => connectionsBetweenNodes().find('.delete'),
() => connectionsBetweenNodes().get('[data-test-id="delete-connection-button"]'),
)
connectionsBetweenNodes()
.get('[data-test-id="delete-connection-button"]')
.first()
.click({ force: true });
},

View File

@@ -45,20 +45,6 @@ switch (scenario) {
startCommand: 'start',
url: 'http://localhost:5678/favicon.ico',
testCommand: 'cypress open',
customEnv: {
CYPRESS_NODE_VIEW_VERSION: 2,
},
});
break;
case 'dev:v1':
runTests({
startCommand: 'develop',
url: 'http://localhost:8080/favicon.ico',
testCommand: 'cypress open',
customEnv: {
CYPRESS_NODE_VIEW_VERSION: 1,
CYPRESS_BASE_URL: 'http://localhost:8080',
},
});
break;
case 'dev':
@@ -67,7 +53,6 @@ switch (scenario) {
url: 'http://localhost:8080/favicon.ico',
testCommand: 'cypress open',
customEnv: {
CYPRESS_NODE_VIEW_VERSION: 2,
CYPRESS_BASE_URL: 'http://localhost:8080',
},
});
@@ -80,9 +65,6 @@ switch (scenario) {
startCommand: 'start',
url: 'http://localhost:5678/favicon.ico',
testCommand: `cypress run --headless ${specParam}`,
customEnv: {
CYPRESS_NODE_VIEW_VERSION: 2,
},
});
break;
case 'debugFlaky': {
@@ -105,9 +87,6 @@ switch (scenario) {
startCommand: 'start',
url: 'http://localhost:5678/favicon.ico',
testCommand: testCommand,
customEnv: {
CYPRESS_NODE_VIEW_VERSION: 2,
},
failFast: true,
});
break;

View File

@@ -10,7 +10,7 @@ import {
N8N_AUTH_COOKIE,
} from '../constants';
import { WorkflowPage } from '../pages';
import { getUniqueWorkflowName, isCanvasV2 } from '../utils/workflowUtils';
import { getUniqueWorkflowName } from '../utils/workflowUtils';
Cypress.Commands.add('setAppDate', (targetDate: number | Date) => {
cy.window().then((win) => {
@@ -26,10 +26,6 @@ Cypress.Commands.add('getByTestId', (selector, ...args) => {
return cy.get(`[data-test-id="${selector}"]`, ...args);
});
Cypress.Commands.add('ifCanvasVersion', (getterV1, getterV2) => {
return isCanvasV2() ? getterV2() : getterV1();
});
Cypress.Commands.add(
'createFixtureWorkflow',
(fixtureKey: string, workflowName = getUniqueWorkflowName()) => {
@@ -74,15 +70,6 @@ Cypress.Commands.add('signin', ({ email, password }) => {
})
.then((response) => {
Cypress.env('currentUserId', response.body.data.id);
// @TODO Remove this once the switcher is removed
cy.window().then((win) => {
win.localStorage.setItem('NodeView.migrated.release', 'true');
win.localStorage.setItem('NodeView.switcher.discovered.beta', 'true');
const nodeViewVersion = Cypress.env('NODE_VIEW_VERSION');
win.localStorage.setItem('NodeView.version', nodeViewVersion ?? '1');
});
});
});
});
@@ -219,15 +206,7 @@ Cypress.Commands.add('draganddrop', (draggableSelector, droppableSelector, optio
const pageY = coords.top + coords.height / 2;
if (draggableSelector) {
cy.ifCanvasVersion(
() => {
// We can't use realMouseDown here because it hangs headless run
cy.get(draggableSelector).trigger('mousedown');
},
() => {
cy.get(draggableSelector).realMouseDown();
},
);
cy.get(draggableSelector).realMouseDown();
}
// We don't chain these commands to make sure cy.get is re-trying correctly
cy.get(droppableSelector).realMouseMove(0, 0);

View File

@@ -28,7 +28,6 @@ declare global {
selector: string,
...args: Array<Partial<Loggable & Timeoutable & Withinable & Shadow> | undefined>
): Chainable<JQuery<HTMLElement>>;
ifCanvasVersion<T1, T2>(getterV1: () => T1, getterV2: () => T2): T1 | T2;
findChildByTestId(childTestId: string): Chainable<JQuery<HTMLElement>>;
/**
* Creates a workflow from the given fixture and optionally renames it.

View File

@@ -3,7 +3,3 @@ import { nanoid } from 'nanoid';
export function getUniqueWorkflowName(workflowNamePrefix?: string) {
return workflowNamePrefix ? `${workflowNamePrefix} ${nanoid(12)}` : nanoid(12);
}
export function isCanvasV2() {
return Cypress.env('NODE_VIEW_VERSION') === 2;
}