Skip to content

Commit

Permalink
Merge branch 'master' into ado-1061-banners-rework
Browse files Browse the repository at this point in the history
* master:
  refactor(core): Implement soft-deletions for executions (#7092)
  docs(Google Sheets Node): Operations naming update (no-changelog) (#7211)
  fix(core): Make parsing of content-type and content-disposition headers more flexible (#7217)
  fix(HTML Node): Add pairedItem support for 'Convert to HTML Table' operation (#7196)
  fix(HTTP Request Node): Decrease default timeout to 5min (#7177)
  feat(Linear Node): Add support for OAuth2 (#7201)
  refactor: Ignore large-scale revisions (no-changelog) (#7210)
  fix(core): Resolve domains to IPv4 first (#7206)
  ci: Fix tests failing on MySQL (no-changelog) (#7208)
  feat(Set Node): Overhaul (#6348)
  fix: Attempt license renewal when n8n starts (no-changelog) (#7204)
  • Loading branch information
MiloradFilipovic committed Sep 20, 2023
2 parents e86137a + cd08c8e commit 319864e
Show file tree
Hide file tree
Showing 95 changed files with 3,481 additions and 835 deletions.
9 changes: 9 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Commits of large-scale changes to exclude from `git blame` results

# Set up linting and formatting (#2120)

56c4c6991fb21ba4b7bdcd22c929f63cc1d1defe

# refactor(editor): Apply Prettier (no-changelog) #4920

5ca2148c7ed06c90f999508928b7a51f9ac7a788
1 change: 1 addition & 0 deletions cypress/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const MANUAL_TRIGGER_NODE_DISPLAY_NAME = 'When clicking "Execute Workflow
export const SCHEDULE_TRIGGER_NODE_NAME = 'Schedule Trigger';
export const CODE_NODE_NAME = 'Code';
export const SET_NODE_NAME = 'Set';
export const EDIT_FIELDS_SET_NODE_NAME = 'Edit Fields';
export const IF_NODE_NAME = 'IF';
export const MERGE_NODE_NAME = 'Merge';
export const SWITCH_NODE_NAME = 'Switch';
Expand Down
7 changes: 4 additions & 3 deletions cypress/e2e/10-undo-redo.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CODE_NODE_NAME, SET_NODE_NAME } from './../constants';
import { CODE_NODE_NAME, SET_NODE_NAME, EDIT_FIELDS_SET_NODE_NAME } from './../constants';
import { SCHEDULE_TRIGGER_NODE_NAME } from '../constants';
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
import { NDV } from '../pages/ndv';
Expand Down Expand Up @@ -274,7 +274,8 @@ describe('Undo/Redo', () => {

WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME);
// WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
WorkflowPage.actions.zoomToFit();

Expand All @@ -287,7 +288,7 @@ describe('Undo/Redo', () => {
cy.drag('[data-test-id="canvas-node"].jtk-drag-selected', [50, 150], { clickToFinish: true });
WorkflowPage.getters.canvasNodes().first().should('have.attr', 'style', movedPosition);
// Delete the set node
WorkflowPage.getters.canvasNodeByName(SET_NODE_NAME).click().click();
WorkflowPage.getters.canvasNodeByName(EDIT_FIELDS_SET_NODE_NAME).click().click();
cy.get('body').type('{backspace}');

// First undo: Should return deleted node
Expand Down
25 changes: 16 additions & 9 deletions cypress/e2e/12-canvas-actions.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
CODE_NODE_NAME,
SCHEDULE_TRIGGER_NODE_NAME,
SET_NODE_NAME,
EDIT_FIELDS_SET_NODE_NAME,
IF_NODE_NAME,
HTTP_REQUEST_NODE_NAME,
} from './../constants';
Expand All @@ -25,24 +25,27 @@ describe('Canvas Actions', () => {
});

it('should connect and disconnect a simple node', () => {
WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME);
WorkflowPage.getters.nodeViewBackground().click(600, 200, { force: true });
cy.get('.jtk-connector').should('have.length', 1);
WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME);

// Change connection from Set to Set1
cy.draganddrop(
WorkflowPage.getters.getEndpointSelector('input', SET_NODE_NAME),
WorkflowPage.getters.getEndpointSelector('input', `${SET_NODE_NAME}1`),
WorkflowPage.getters.getEndpointSelector('input', EDIT_FIELDS_SET_NODE_NAME),
WorkflowPage.getters.getEndpointSelector('input', `${EDIT_FIELDS_SET_NODE_NAME}1`),
);

WorkflowPage.getters
.canvasNodeInputEndpointByName(`${SET_NODE_NAME}1`)
.canvasNodeInputEndpointByName(`${EDIT_FIELDS_SET_NODE_NAME}1`)
.should('have.class', 'jtk-endpoint-connected');

cy.get('.jtk-connector').should('have.length', 1);
// Disconnect Set1
cy.drag(WorkflowPage.getters.getEndpointSelector('input', `${SET_NODE_NAME}1`), [-200, 100]);
cy.drag(
WorkflowPage.getters.getEndpointSelector('input', `${EDIT_FIELDS_SET_NODE_NAME}1`),
[-200, 100],
);
cy.get('.jtk-connector').should('have.length', 0);
});

Expand Down Expand Up @@ -117,9 +120,13 @@ describe('Canvas Actions', () => {
it('should add node between two connected nodes', () => {
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME);
WorkflowPage.actions.zoomToFit();
WorkflowPage.actions.addNodeBetweenNodes(CODE_NODE_NAME, SET_NODE_NAME, HTTP_REQUEST_NODE_NAME);
WorkflowPage.actions.addNodeBetweenNodes(
CODE_NODE_NAME,
EDIT_FIELDS_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
Expand Down
20 changes: 10 additions & 10 deletions cypress/e2e/12-canvas.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
CODE_NODE_NAME,
SCHEDULE_TRIGGER_NODE_NAME,
SET_NODE_NAME,
EDIT_FIELDS_SET_NODE_NAME,
SWITCH_NODE_NAME,
MERGE_NODE_NAME,
} from './../constants';
Expand All @@ -30,15 +30,15 @@ describe('Canvas Node Manipulation and Navigation', () => {
for (let i = 0; i < 4; i++) {
WorkflowPage.getters.canvasNodePlusEndpointByName(SWITCH_NODE_NAME, i).click({ force: true });
WorkflowPage.getters.nodeCreatorSearchBar().should('be.visible');
WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME, false);
WorkflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, false);
WorkflowPage.actions.zoomToFit();
}
WorkflowPage.actions.saveWorkflowOnButtonClick();
cy.reload();
cy.waitForLoad();
// Make sure all connections are there after reload
for (let i = 0; i < 4; i++) {
const setName = `${SET_NODE_NAME}${i > 0 ? i : ''}`;
const setName = `${EDIT_FIELDS_SET_NODE_NAME}${i > 0 ? i : ''}`;
WorkflowPage.getters
.canvasNodeInputEndpointByName(setName)
.should('have.class', 'jtk-endpoint-connected');
Expand All @@ -49,7 +49,7 @@ describe('Canvas Node Manipulation and Navigation', () => {
WorkflowPage.actions.addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
WorkflowPage.getters.canvasNodeByName(MANUAL_TRIGGER_NODE_DISPLAY_NAME).click();
for (let i = 0; i < 2; i++) {
WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME, true);
WorkflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, true);
WorkflowPage.getters.nodeViewBackground().click(600 + i * 100, 200, { force: true });
}
WorkflowPage.actions.zoomToFit();
Expand All @@ -60,18 +60,18 @@ describe('Canvas Node Manipulation and Navigation', () => {
// Connect manual to Set1
cy.draganddrop(
WorkflowPage.getters.getEndpointSelector('output', MANUAL_TRIGGER_NODE_DISPLAY_NAME),
WorkflowPage.getters.getEndpointSelector('input', `${SET_NODE_NAME}1`),
WorkflowPage.getters.getEndpointSelector('input', `${EDIT_FIELDS_SET_NODE_NAME}1`),
);

cy.get('.rect-input-endpoint.jtk-endpoint-connected').should('have.length', 2);

// Connect Set1 and Set2 to merge
cy.draganddrop(
WorkflowPage.getters.getEndpointSelector('plus', SET_NODE_NAME),
WorkflowPage.getters.getEndpointSelector('plus', EDIT_FIELDS_SET_NODE_NAME),
WorkflowPage.getters.getEndpointSelector('input', MERGE_NODE_NAME, 0),
);
cy.draganddrop(
WorkflowPage.getters.getEndpointSelector('plus', `${SET_NODE_NAME}1`),
WorkflowPage.getters.getEndpointSelector('plus', `${EDIT_FIELDS_SET_NODE_NAME}1`),
WorkflowPage.getters.getEndpointSelector('input', MERGE_NODE_NAME, 1),
);

Expand All @@ -94,7 +94,7 @@ describe('Canvas Node Manipulation and Navigation', () => {
WorkflowPage.actions.addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
WorkflowPage.getters.canvasNodeByName(MANUAL_TRIGGER_NODE_DISPLAY_NAME).click();
for (let i = 0; i < 3; i++) {
WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME, true);
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME, true);
}
WorkflowPage.actions.zoomToFit();
WorkflowPage.actions.executeWorkflow();
Expand All @@ -103,7 +103,7 @@ describe('Canvas Node Manipulation and Navigation', () => {
cy.get('.data-count').should('have.length', 4);
cy.get('.plus-draggable-endpoint').should('have.class', 'ep-success');

WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
WorkflowPage.actions.zoomToFit();

cy.get('.plus-draggable-endpoint').filter(':visible').should('not.have.class', 'ep-success');
Expand Down Expand Up @@ -134,7 +134,7 @@ describe('Canvas Node Manipulation and Navigation', () => {
it('should delete node between two connected nodes', () => {
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME);
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();
Expand Down
59 changes: 30 additions & 29 deletions cypress/e2e/13-pinning.cy.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {
HTTP_REQUEST_NODE_NAME,
MANUAL_TRIGGER_NODE_NAME,
PIPEDRIVE_NODE_NAME,
SET_NODE_NAME,
} from '../constants';
// import {
// HTTP_REQUEST_NODE_NAME,
// MANUAL_TRIGGER_NODE_NAME,
// PIPEDRIVE_NODE_NAME,
// EDIT_FIELDS_SET_NODE_NAME,
// } from '../constants';
import { WorkflowPage, NDV } from '../pages';

const workflowPage = new WorkflowPage();
Expand Down Expand Up @@ -69,34 +69,35 @@ describe('Data pinning', () => {
ndv.getters.outputTbodyCell(1, 0).should('include.text', 1);
});

it('Should be able to reference paired items in a node located before pinned data', () => {
workflowPage.actions.addInitialNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
workflowPage.actions.addNodeToCanvas(HTTP_REQUEST_NODE_NAME, true, true);
ndv.actions.setPinnedData([{ http: 123 }]);
ndv.actions.close();
//TODO: Update Edit Fields (Set) node to a new version
// it('Should be able to reference paired items in a node located before pinned data', () => {
// workflowPage.actions.addInitialNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
// workflowPage.actions.addNodeToCanvas(HTTP_REQUEST_NODE_NAME, true, true);
// ndv.actions.setPinnedData([{ http: 123 }]);
// ndv.actions.close();

workflowPage.actions.addNodeToCanvas(PIPEDRIVE_NODE_NAME, true, true);
ndv.actions.setPinnedData(Array(3).fill({ pipedrive: 123 }));
ndv.actions.close();
// workflowPage.actions.addNodeToCanvas(PIPEDRIVE_NODE_NAME, true, true);
// ndv.actions.setPinnedData(Array(3).fill({ pipedrive: 123 }));
// ndv.actions.close();

workflowPage.actions.addNodeToCanvas(SET_NODE_NAME, true, true);
setExpressionOnStringValueInSet(`{{ $('${HTTP_REQUEST_NODE_NAME}').item`);
// workflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, true, true);
// setExpressionOnStringValueInSet(`{{ $('${HTTP_REQUEST_NODE_NAME}').item`);

const output = '[Object: {"json": {"http": 123}, "pairedItem": {"item": 0}}]';
// const output = '[Object: {"json": {"http": 123}, "pairedItem": {"item": 0}}]';

cy.get('div').contains(output).should('be.visible');
});
// cy.get('div').contains(output).should('be.visible');
// });
});

function setExpressionOnStringValueInSet(expression: string) {
cy.get('button').contains('Execute node').click();
cy.get('input[placeholder="Add Value"]').click();
cy.get('span').contains('String').click();
// function setExpressionOnStringValueInSet(expression: string) {
// cy.get('button').contains('Execute node').click();
// cy.get('input[placeholder="Add Value"]').click();
// cy.get('span').contains('String').click();

ndv.getters.nthParam(3).contains('Expression').invoke('show').click();
// ndv.getters.nthParam(3).contains('Expression').invoke('show').click();

ndv.getters
.inlineExpressionEditorInput()
.clear()
.type(expression, { parseSpecialCharSequences: false });
}
// ndv.getters
// .inlineExpressionEditorInput()
// .clear()
// .type(expression, { parseSpecialCharSequences: false });
// }
24 changes: 12 additions & 12 deletions cypress/e2e/14-data-transformation-expressions.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('Data transformation expressions', () => {
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
ndv.actions.setPinnedData([{ myStr: 'Monday' }]);
ndv.actions.close();
addSet();
addEditFields();

const input = '{{$json.myStr.toLowerCase() + " is " + "today".toUpperCase()';
const output = 'monday is TODAY';
Expand All @@ -27,7 +27,7 @@ describe('Data transformation expressions', () => {
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
ndv.actions.setPinnedData([{ myStr: 'hello@n8n.io is an email' }]);
ndv.actions.close();
addSet();
addEditFields();

const input = '{{$json.myStr.extractEmail() + " " + $json.myStr.isEmpty()';
const output = 'hello@n8n.io false';
Expand All @@ -42,7 +42,7 @@ describe('Data transformation expressions', () => {
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
ndv.actions.setPinnedData([{ myNum: 9.123 }]);
ndv.actions.close();
addSet();
addEditFields();

const input = '{{$json.myNum.toPrecision(3)';
const output = '9.12';
Expand All @@ -57,7 +57,7 @@ describe('Data transformation expressions', () => {
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
ndv.actions.setPinnedData([{ myStr: 'hello@n8n.io is an email' }]);
ndv.actions.close();
addSet();
addEditFields();

const input = '{{$json.myStr.extractEmail() + " " + $json.myStr.isEmpty()';
const output = 'hello@n8n.io false';
Expand All @@ -72,7 +72,7 @@ describe('Data transformation expressions', () => {
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
ndv.actions.setPinnedData([{ myArr: [1, 2, 3] }]);
ndv.actions.close();
addSet();
addEditFields();
const input = '{{$json.myArr.includes(1) + " " + $json.myArr[2]';
const output = 'true 3';

Expand All @@ -86,7 +86,7 @@ describe('Data transformation expressions', () => {
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
ndv.actions.setPinnedData([{ myArr: [1, 2, 3] }]);
ndv.actions.close();
addSet();
addEditFields();

const input = '{{$json.myArr.first() + " " + $json.myArr.last()';
const output = '1 3';
Expand All @@ -102,10 +102,10 @@ describe('Data transformation expressions', () => {
// utils
// ----------------------------------

const addSet = () => {
wf.actions.addNodeToCanvas('Set', true, true);
ndv.getters.parameterInput('keepOnlySet').find('.el-switch').click(); // shorten output
cy.get('input[placeholder="Add Value"]').click();
cy.get('span').contains('String').click();
ndv.getters.nthParam(3).contains('Expression').invoke('show').click(); // Values to Set > String > Value
const addEditFields = () => {
wf.actions.addNodeToCanvas('Edit Fields', true, true);
cy.get('.fixed-collection-parameter > :nth-child(2) > .button > span').click();
ndv.getters.parameterInput('include').click(); // shorten output
cy.get('div').contains('No Input Fields').click();
ndv.getters.nthParam(4).contains('Expression').invoke('show').click();
};
Loading

0 comments on commit 319864e

Please sign in to comment.