Skip to content

Commit

Permalink
Remerge n8n 3/22 (#56)
Browse files Browse the repository at this point in the history
* Adds new n8n without version

* Adds n8n merge with permission updates
  • Loading branch information
andyjoyous authored Mar 22, 2024
1 parent 64981cf commit d6fb50f
Show file tree
Hide file tree
Showing 1,120 changed files with 38,139 additions and 20,393 deletions.
181 changes: 180 additions & 1 deletion CHANGELOG.md

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions cypress/composables/ndv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Getters
*/

import { getVisibleSelect } from "../utils";

export function getCredentialSelect(eq = 0) {
return cy.getByTestId('node-credentials-select').eq(eq);
}
Expand Down Expand Up @@ -71,3 +73,12 @@ export function clickExecuteNode() {
export function setParameterInputByName(name: string, value: string) {
getParameterInputByName(name).clear().type(value);
}

export function toggleParameterCheckboxInputByName(name: string) {
getParameterInputByName(name).find('input[type="checkbox"]').realClick()
}

export function setParameterSelectByContent(name: string, content: string) {
getParameterInputByName(name).realClick();
getVisibleSelect().find('.option-headline').contains(content).click();
}
172 changes: 118 additions & 54 deletions cypress/e2e/11-inline-expression-editor.cy.ts
Original file line number Diff line number Diff line change
@@ -1,72 +1,136 @@
import { NDV } from '../pages/ndv';
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';

const ndv = new NDV();
const WorkflowPage = new WorkflowPageClass();

describe('Inline expression editor', () => {
beforeEach(() => {
WorkflowPage.actions.visit();
WorkflowPage.actions.addInitialNodeToCanvas('Manual');
WorkflowPage.actions.addNodeToCanvas('Hacker News');
WorkflowPage.actions.openNode('Hacker News');
WorkflowPage.actions.openInlineExpressionEditor();

WorkflowPage.actions.addInitialNodeToCanvas('Schedule');
cy.on('uncaught:exception', (err) => err.name !== 'ExpressionError');
});

it('should resolve primitive resolvables', () => {
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('1 + 2');
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^3$/);
WorkflowPage.getters.inlineExpressionEditorInput().clear();

WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('"ab"');
WorkflowPage.getters.inlineExpressionEditorInput().type('{rightArrow}+');
WorkflowPage.getters.inlineExpressionEditorInput().type('"cd"');
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^abcd$/);
WorkflowPage.getters.inlineExpressionEditorInput().clear();

WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('true && false');
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^false$/);
});
describe('Static data', () => {
beforeEach(() => {
WorkflowPage.actions.addNodeToCanvas('Hacker News');
WorkflowPage.actions.openNode('Hacker News');
WorkflowPage.actions.openInlineExpressionEditor();
});

it('should resolve object resolvables', () => {
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters
.inlineExpressionEditorInput()
.type('{ a: 1 }', { parseSpecialCharSequences: false });
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^\[Object: \{"a": 1\}\]$/);
WorkflowPage.getters.inlineExpressionEditorInput().clear();

WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters
.inlineExpressionEditorInput()
.type('{ a: 1 }.a', { parseSpecialCharSequences: false });
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^1$/);
});
it('should resolve primitive resolvables', () => {
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('1 + 2');
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^3$/);
WorkflowPage.getters.inlineExpressionEditorInput().clear();

WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('"ab"');
WorkflowPage.getters.inlineExpressionEditorInput().type('{rightArrow}+');
WorkflowPage.getters.inlineExpressionEditorInput().type('"cd"');
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^abcd$/);
WorkflowPage.getters.inlineExpressionEditorInput().clear();

WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('true && false');
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^false$/);
});

it('should resolve object resolvables', () => {
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters
.inlineExpressionEditorInput()
.type('{ a: 1 }', { parseSpecialCharSequences: false });
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^\[Object: \{"a": 1\}\]$/);
WorkflowPage.getters.inlineExpressionEditorInput().clear();

it('should resolve array resolvables', () => {
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('[1, 2, 3]');
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^\[Array: \[1,2,3\]\]$/);
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters
.inlineExpressionEditorInput()
.type('{ a: 1 }.a', { parseSpecialCharSequences: false });
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^1$/);
});

WorkflowPage.getters.inlineExpressionEditorInput().clear();
it('should resolve array resolvables', () => {
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('[1, 2, 3]');
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^\[Array: \[1,2,3\]\]$/);

WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('[1, 2, 3]');
WorkflowPage.getters.inlineExpressionEditorInput().type('[0]');
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^1$/);
WorkflowPage.getters.inlineExpressionEditorInput().clear();

WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('[1, 2, 3]');
WorkflowPage.getters.inlineExpressionEditorInput().type('[0]');
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^1$/);
});
});

it('should resolve $parameter[]', () => {
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
// Resolving $parameter is slow, especially on CI runner
WorkflowPage.getters.inlineExpressionEditorInput().type('$parameter["operation"]');
WorkflowPage.getters.inlineExpressionEditorOutput().should('have.text', 'getAll');
describe('Dynamic data', () => {
beforeEach(() => {
WorkflowPage.actions.openNode('Schedule Trigger');
ndv.actions.setPinnedData([{ myStr: 'Monday' }]);
ndv.actions.close();
WorkflowPage.actions.addNodeToCanvas('No Operation');
WorkflowPage.actions.addNodeToCanvas('Hacker News');
WorkflowPage.actions.openNode('Hacker News');
WorkflowPage.actions.openInlineExpressionEditor();
});

it('should resolve $parameter[]', () => {
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
// Resolving $parameter is slow, especially on CI runner
WorkflowPage.getters.inlineExpressionEditorInput().type('$parameter["operation"]');
WorkflowPage.getters.inlineExpressionEditorOutput().should('have.text', 'getAll');
});

it('should resolve input: $json,$input,$(nodeName)', () => {
// Previous nodes have not run, input is empty
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('$json.myStr');
WorkflowPage.getters
.inlineExpressionEditorOutput()
.should('have.text', '[Execute previous nodes for preview]');
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('$input.item.json.myStr');
WorkflowPage.getters
.inlineExpressionEditorOutput()
.should('have.text', '[Execute previous nodes for preview]');
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters
.inlineExpressionEditorInput()
.type("$('Schedule Trigger').item.json.myStr");
WorkflowPage.getters
.inlineExpressionEditorOutput()
.should('have.text', '[Execute previous nodes for preview]');

// Run workflow
ndv.actions.close();
WorkflowPage.actions.executeNode('No Operation');
WorkflowPage.actions.openNode('Hacker News');
WorkflowPage.actions.openInlineExpressionEditor();

// Previous nodes have run, input can be resolved
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('$json.myStr');
WorkflowPage.getters.inlineExpressionEditorOutput().should('have.text', 'Monday');
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters.inlineExpressionEditorInput().type('$input.item.json.myStr');
WorkflowPage.getters.inlineExpressionEditorOutput().should('have.text', 'Monday');
WorkflowPage.getters.inlineExpressionEditorInput().clear();
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
WorkflowPage.getters
.inlineExpressionEditorInput()
.type("$('Schedule Trigger').item.json.myStr");
WorkflowPage.getters.inlineExpressionEditorOutput().should('have.text', 'Monday');
});
});
});
4 changes: 3 additions & 1 deletion cypress/e2e/13-pinning.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,5 +195,7 @@ function setExpressionOnStringValueInSet(expression: string) {
ndv.getters
.inlineExpressionEditorInput()
.clear()
.type(expression, { parseSpecialCharSequences: false });
.type(expression, { parseSpecialCharSequences: false })
// hide autocomplete
.type('{esc}');
}
6 changes: 6 additions & 0 deletions cypress/e2e/14-data-transformation-expressions.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ describe('Data transformation expressions', () => {
const output = 'monday is TODAY';

ndv.getters.inlineExpressionEditorInput().clear().type(input);
ndv.getters.inlineExpressionEditorOutput().should('have.text', output);
ndv.actions.execute();
ndv.getters.outputDataContainer().should('be.visible');
ndv.getters.outputDataContainer().contains(output);
Expand All @@ -34,6 +35,7 @@ describe('Data transformation expressions', () => {
const output = '[email protected] false';

ndv.getters.inlineExpressionEditorInput().clear().type(input);
ndv.getters.inlineExpressionEditorOutput().should('have.text', output);
ndv.actions.execute();
ndv.getters.outputDataContainer().should('be.visible');
ndv.getters.outputDataContainer().contains(output);
Expand All @@ -49,6 +51,7 @@ describe('Data transformation expressions', () => {
const output = '9.12';

ndv.getters.inlineExpressionEditorInput().clear().type(input);
ndv.getters.inlineExpressionEditorOutput().should('have.text', output);
ndv.actions.execute();
ndv.getters.outputDataContainer().should('be.visible');
ndv.getters.outputDataContainer().contains(output);
Expand All @@ -64,6 +67,7 @@ describe('Data transformation expressions', () => {
const output = '[email protected] false';

ndv.getters.inlineExpressionEditorInput().clear().type(input);
ndv.getters.inlineExpressionEditorOutput().should('have.text', output);
ndv.actions.execute();
ndv.getters.outputDataContainer().should('be.visible');
ndv.getters.outputDataContainer().contains(output);
Expand All @@ -78,6 +82,7 @@ describe('Data transformation expressions', () => {
const output = 'true 3';

ndv.getters.inlineExpressionEditorInput().clear().type(input);
ndv.getters.inlineExpressionEditorOutput().should('have.text', output);
ndv.actions.execute();
ndv.getters.outputDataContainer().find('[class*=value_]').should('exist');
ndv.getters.outputDataContainer().find('[class*=value_]').should('contain', output);
Expand All @@ -93,6 +98,7 @@ describe('Data transformation expressions', () => {
const output = '1 3';

ndv.getters.inlineExpressionEditorInput().clear().type(input);
ndv.getters.inlineExpressionEditorOutput().should('have.text', output);
ndv.actions.execute();
ndv.getters.outputDataContainer().find('[class*=value_]').should('exist');
ndv.getters.outputDataContainer().find('[class*=value_]').should('contain', output);
Expand Down
18 changes: 7 additions & 11 deletions cypress/e2e/14-mapping.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,6 @@ describe('Data mapping', () => {
ndv.getters
.inlineExpressionEditorInput()
.should('have.text', `{{ $('${SCHEDULE_TRIGGER_NODE_NAME}').item.json.input[0].count }}`);
ndv.getters
.parameterExpressionPreview('value')
.invoke('text')
.invoke('replace', /\u00a0/g, ' ')
.should('equal', '[ERROR: no data, execute "Schedule Trigger" node first]');

ndv.actions.switchInputMode('Table');
ndv.actions.mapDataFromHeader(1, 'value');
Expand All @@ -195,7 +190,6 @@ describe('Data mapping', () => {
'have.text',
`{{ $('${SCHEDULE_TRIGGER_NODE_NAME}').item.json.input[0].count }} {{ $('${SCHEDULE_TRIGGER_NODE_NAME}').item.json.input }}`,
);
ndv.actions.validateExpressionPreview('value', ' ');

ndv.actions.selectInputNode('Set');

Expand Down Expand Up @@ -259,7 +253,6 @@ describe('Data mapping', () => {
workflowPage.actions.openNode('Set');

ndv.actions.typeIntoParameterInput('value', 'delete me');
ndv.actions.dismissMappingTooltip();

ndv.actions.typeIntoParameterInput('name', 'test');

Expand Down Expand Up @@ -291,8 +284,8 @@ describe('Data mapping', () => {
ndv.actions.clearParameterInput('value');
cy.get('body').type('{esc}');

ndv.getters.parameterInput('keepOnlySet').find('input[type="checkbox"]').should('exist');
ndv.getters.parameterInput('keepOnlySet').find('input[type="text"]').should('not.exist');
ndv.getters.parameterInput('includeOtherFields').find('input[type="checkbox"]').should('exist');
ndv.getters.parameterInput('includeOtherFields').find('input[type="text"]').should('not.exist');
ndv.getters
.inputDataContainer()
.should('exist')
Expand All @@ -302,9 +295,12 @@ describe('Data mapping', () => {
.realMouseMove(100, 100);
cy.wait(50);

ndv.getters.parameterInput('keepOnlySet').find('input[type="checkbox"]').should('not.exist');
ndv.getters
.parameterInput('keepOnlySet')
.parameterInput('includeOtherFields')
.find('input[type="checkbox"]')
.should('not.exist');
ndv.getters
.parameterInput('includeOtherFields')
.find('input[type="text"]')
.should('exist')
.invoke('css', 'border')
Expand Down
12 changes: 8 additions & 4 deletions cypress/e2e/16-form-trigger-node.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ describe('n8n Form Trigger', () => {
':nth-child(3) > .border-top-dashed > .parameter-input-list-wrapper > :nth-child(1) > .parameter-item',
)
.find('input[placeholder*="e.g. What is your name?"]')
.type('Test Field 3');
.type('Test Field 3')
.blur();
cy.get(
':nth-child(3) > .border-top-dashed > .parameter-input-list-wrapper > :nth-child(2) > .parameter-item',
).click();
Expand All @@ -53,7 +54,8 @@ describe('n8n Form Trigger', () => {
':nth-child(4) > .border-top-dashed > .parameter-input-list-wrapper > :nth-child(1) > .parameter-item',
)
.find('input[placeholder*="e.g. What is your name?"]')
.type('Test Field 4');
.type('Test Field 4')
.blur();
cy.get(
':nth-child(4) > .border-top-dashed > .parameter-input-list-wrapper > :nth-child(2) > .parameter-item',
).click();
Expand All @@ -65,12 +67,14 @@ describe('n8n Form Trigger', () => {
':nth-child(4) > :nth-child(1) > :nth-child(2) > :nth-child(3) > .multi-parameter > .fixed-collection-parameter > .fixed-collection-parameter-property > :nth-child(1) > :nth-child(1)',
)
.find('input')
.type('Option 1');
.type('Option 1')
.blur();
cy.get(
':nth-child(4) > :nth-child(1) > :nth-child(2) > :nth-child(3) > .multi-parameter > .fixed-collection-parameter > .fixed-collection-parameter-property > :nth-child(1) > :nth-child(2)',
)
.find('input')
.type('Option 2');
.type('Option 2')
.blur();

//add optional submitted message
cy.get('.param-options').click();
Expand Down
4 changes: 2 additions & 2 deletions cypress/e2e/16-webhook-node.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ describe('Webhook Trigger node', async () => {
workflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME);
workflowPage.actions.openNode(EDIT_FIELDS_SET_NODE_NAME);
ndv.getters.assignmentCollectionAdd('assignments').click();
ndv.getters.assignmentName('assignments').type('data');
ndv.getters.assignmentName('assignments').type('data').find('input').blur();
ndv.getters.assignmentType('assignments').click();
ndv.getters.assignmentValue('assignments').paste(cowBase64);

Expand Down Expand Up @@ -313,7 +313,7 @@ const addEditFields = () => {
workflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME);
workflowPage.actions.openNode(EDIT_FIELDS_SET_NODE_NAME);
ndv.getters.assignmentCollectionAdd('assignments').click();
ndv.getters.assignmentName('assignments').type('MyValue');
ndv.getters.assignmentName('assignments').type('MyValue').find('input').blur();
ndv.getters.assignmentType('assignments').click();
getVisibleSelect().find('li').contains('Number').click();
ndv.getters.assignmentValue('assignments').type('1234');
Expand Down
4 changes: 2 additions & 2 deletions cypress/e2e/18-user-management.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ describe('User Management', { disableAutoLogin: true }, () => {
.logo()
.should('have.attr', 'src')
.then((src) => {
expect(src).to.include('/n8n-dev-logo-dark-mode.svg');
expect(src).to.include('/static/logo/channel/dev-dark.svg');
});

cy.visit(personalSettingsPage.url);
Expand All @@ -143,7 +143,7 @@ describe('User Management', { disableAutoLogin: true }, () => {
.logo()
.should('have.attr', 'src')
.then((src) => {
expect(src).to.include('/n8n-dev-logo.svg');
expect(src).to.include('/static/logo/channel/dev.svg');
});
});

Expand Down
Loading

0 comments on commit d6fb50f

Please sign in to comment.