mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-09 22:24:05 -08:00
test: Add more data mapping tests (#5389)
* test: Add more data mapping tests * test: add tests for preview mapping * test: update wording * test: add more tests * test: fix up prev node test * test: stop popup * test: add mapping test for paths * test: revert back param changes * test: fix mapping tests * test: reset db * test: fix up mapping tests * test: fix up mapping tests * test: update tests to be more stable * chore: clean up unused command * fix: fix up before unload bug * fix: fix data transformation tests * test: fix up flaky webhook tests * test: fix up flaky webhook tests * test: fix up flaky dt tests
This commit is contained in:
parent
00befbc75a
commit
b8980f6118
|
@ -4,15 +4,18 @@ const wf = new WorkflowPage();
|
||||||
const ndv = new NDV();
|
const ndv = new NDV();
|
||||||
|
|
||||||
describe('Data transformation expressions', () => {
|
describe('Data transformation expressions', () => {
|
||||||
before(() => {
|
beforeEach(() => {
|
||||||
cy.resetAll();
|
cy.resetAll();
|
||||||
cy.skipSetup();
|
cy.skipSetup();
|
||||||
|
wf.actions.visit();
|
||||||
cy.waitForLoad();
|
cy.waitForLoad();
|
||||||
|
|
||||||
|
cy.window()
|
||||||
|
// @ts-ignore
|
||||||
|
.then(win => win.onBeforeUnload && win.removeEventListener('beforeunload', win.onBeforeUnload));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('$json + native string methods', () => {
|
it('$json + native string methods', () => {
|
||||||
wf.actions.visit();
|
|
||||||
|
|
||||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||||
ndv.actions.setPinnedData([{ myStr: 'Monday' }]);
|
ndv.actions.setPinnedData([{ myStr: 'Monday' }]);
|
||||||
ndv.actions.close();
|
ndv.actions.close();
|
||||||
|
@ -23,12 +26,10 @@ describe('Data transformation expressions', () => {
|
||||||
|
|
||||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||||
ndv.actions.execute();
|
ndv.actions.execute();
|
||||||
ndv.getters.outputDataContainer().contains(output).should('be.visible');
|
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('$json + n8n string methods', () => {
|
it('$json + n8n string methods', () => {
|
||||||
wf.actions.visit();
|
|
||||||
|
|
||||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||||
ndv.actions.setPinnedData([{ myStr: 'hello@n8n.io is an email' }]);
|
ndv.actions.setPinnedData([{ myStr: 'hello@n8n.io is an email' }]);
|
||||||
ndv.actions.close();
|
ndv.actions.close();
|
||||||
|
@ -39,12 +40,10 @@ describe('Data transformation expressions', () => {
|
||||||
|
|
||||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||||
ndv.actions.execute();
|
ndv.actions.execute();
|
||||||
ndv.getters.outputDataContainer().contains(output).should('be.visible');
|
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('$json + native numeric methods', () => {
|
it('$json + native numeric methods', () => {
|
||||||
wf.actions.visit();
|
|
||||||
|
|
||||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||||
ndv.actions.setPinnedData([{ myNum: 9.123 }]);
|
ndv.actions.setPinnedData([{ myNum: 9.123 }]);
|
||||||
ndv.actions.close();
|
ndv.actions.close();
|
||||||
|
@ -55,12 +54,10 @@ describe('Data transformation expressions', () => {
|
||||||
|
|
||||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||||
ndv.actions.execute();
|
ndv.actions.execute();
|
||||||
ndv.getters.outputDataContainer().contains(output).should('be.visible');
|
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('$json + n8n numeric methods', () => {
|
it('$json + n8n numeric methods', () => {
|
||||||
wf.actions.visit();
|
|
||||||
|
|
||||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||||
ndv.actions.setPinnedData([{ myStr: 'hello@n8n.io is an email' }]);
|
ndv.actions.setPinnedData([{ myStr: 'hello@n8n.io is an email' }]);
|
||||||
ndv.actions.close();
|
ndv.actions.close();
|
||||||
|
@ -71,12 +68,10 @@ describe('Data transformation expressions', () => {
|
||||||
|
|
||||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||||
ndv.actions.execute();
|
ndv.actions.execute();
|
||||||
ndv.getters.outputDataContainer().contains(output).should('be.visible');
|
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('$json + native array methods', () => {
|
it('$json + native array methods', () => {
|
||||||
wf.actions.visit();
|
|
||||||
|
|
||||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||||
ndv.actions.setPinnedData([{ myArr: [1, 2, 3] }]);
|
ndv.actions.setPinnedData([{ myArr: [1, 2, 3] }]);
|
||||||
ndv.actions.close();
|
ndv.actions.close();
|
||||||
|
@ -87,12 +82,10 @@ describe('Data transformation expressions', () => {
|
||||||
|
|
||||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||||
ndv.actions.execute();
|
ndv.actions.execute();
|
||||||
ndv.getters.outputDataContainer().contains(output).should('be.visible');
|
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('$json + n8n array methods', () => {
|
it('$json + n8n array methods', () => {
|
||||||
wf.actions.visit();
|
|
||||||
|
|
||||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||||
ndv.actions.setPinnedData([{ myArr: [1, 2, 3] }]);
|
ndv.actions.setPinnedData([{ myArr: [1, 2, 3] }]);
|
||||||
ndv.actions.close();
|
ndv.actions.close();
|
||||||
|
@ -103,7 +96,7 @@ describe('Data transformation expressions', () => {
|
||||||
|
|
||||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||||
ndv.actions.execute();
|
ndv.actions.execute();
|
||||||
ndv.getters.outputDataContainer().contains(output).should('be.visible');
|
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,18 @@ const ndv = new NDV();
|
||||||
const canvasNode = new CanvasNode();
|
const canvasNode = new CanvasNode();
|
||||||
|
|
||||||
describe('Data mapping', () => {
|
describe('Data mapping', () => {
|
||||||
before(() => {
|
beforeEach(() => {
|
||||||
cy.resetAll();
|
cy.resetAll();
|
||||||
cy.skipSetup();
|
cy.skipSetup();
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
workflowPage.actions.visit();
|
workflowPage.actions.visit();
|
||||||
|
cy.waitForLoad();
|
||||||
|
|
||||||
|
cy.window()
|
||||||
|
// @ts-ignore
|
||||||
|
.then(win => win.onBeforeUnload && win.removeEventListener('beforeunload', win.onBeforeUnload))
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should be able to map expressions from table header', () => {
|
it('maps expressions from table header', () => {
|
||||||
cy.fixture('Test_workflow-actions_paste-data.json').then((data) => {
|
cy.fixture('Test_workflow-actions_paste-data.json').then((data) => {
|
||||||
cy.get('body').paste(JSON.stringify(data));
|
cy.get('body').paste(JSON.stringify(data));
|
||||||
});
|
});
|
||||||
|
@ -34,4 +36,188 @@ describe('Data mapping', () => {
|
||||||
ndv.actions.mapDataFromHeader(2, 'value');
|
ndv.actions.mapDataFromHeader(2, 'value');
|
||||||
ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.timestamp }} {{ $json["Readable date"] }}');
|
ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.timestamp }} {{ $json["Readable date"] }}');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('maps expressions from table json, and resolves value based on hover', () => {
|
||||||
|
cy.fixture('Test_workflow_3.json').then((data) => {
|
||||||
|
cy.get('body').paste(JSON.stringify(data));
|
||||||
|
});
|
||||||
|
|
||||||
|
canvasNode.actions.openNode('Set');
|
||||||
|
ndv.actions.switchInputMode('Table');
|
||||||
|
ndv.getters.inputDataContainer().get('table', { timeout: 10000 }).should('exist');
|
||||||
|
|
||||||
|
ndv.getters.parameterInput('name').should('have.length', 1).find('input').should('have.value', 'other');
|
||||||
|
ndv.getters.parameterInput('value').should('have.length', 1).find('input').should('have.value', '');
|
||||||
|
|
||||||
|
ndv.getters.inputTbodyCell(1, 0).find('span').contains('count').trigger('mousedown', {force: true});
|
||||||
|
ndv.actions.mapToParameter('value');
|
||||||
|
|
||||||
|
ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.input[0].count }}');
|
||||||
|
ndv.getters.parameterExpressionPreview('value').should('include.text', '0')
|
||||||
|
|
||||||
|
ndv.getters.inputTbodyCell(1, 0).realHover();
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('include.text', '0')
|
||||||
|
.invoke('css', 'color')
|
||||||
|
.should('equal', 'rgb(125, 125, 135)');
|
||||||
|
|
||||||
|
ndv.getters.inputTbodyCell(2, 0).realHover();
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('include.text', '1')
|
||||||
|
.invoke('css', 'color')
|
||||||
|
.should('equal', 'rgb(125, 125, 135)');
|
||||||
|
|
||||||
|
ndv.actions.execute();
|
||||||
|
|
||||||
|
ndv.getters.outputTbodyCell(1, 0).realHover();
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('include.text', '0')
|
||||||
|
.invoke('css', 'color')
|
||||||
|
.should('equal', 'rgb(125, 125, 135)'); // todo update color
|
||||||
|
|
||||||
|
ndv.getters.outputTbodyCell(2, 0).realHover();
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('include.text', '1')
|
||||||
|
.invoke('css', 'color')
|
||||||
|
.should('equal', 'rgb(125, 125, 135)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('maps expressions from json view', () => {
|
||||||
|
cy.fixture('Test_workflow_3.json').then((data) => {
|
||||||
|
cy.get('body').paste(JSON.stringify(data));
|
||||||
|
});
|
||||||
|
|
||||||
|
canvasNode.actions.openNode('Set');
|
||||||
|
ndv.actions.switchInputMode('JSON');
|
||||||
|
|
||||||
|
ndv.getters.inputDataContainer().should('exist').find('.json-data')
|
||||||
|
.should('have.text', '[{"input":[{"count":0,"with space":"!!","with.dot":"!!","with"quotes":"!!"}]},{"input":[{"count":1}]}]')
|
||||||
|
.find('span').contains('"count"')
|
||||||
|
.realMouseDown();
|
||||||
|
|
||||||
|
ndv.actions.mapToParameter('value');
|
||||||
|
ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.input[0].count }}');
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('include.text', '0');
|
||||||
|
|
||||||
|
ndv.getters.inputDataContainer().find('.json-data')
|
||||||
|
.find('span').contains('"input"')
|
||||||
|
.realMouseDown();
|
||||||
|
|
||||||
|
ndv.actions.mapToParameter('value');
|
||||||
|
ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.input[0].count }} {{ $json.input }}');
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('include.text', '0 [object Object]');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('maps expressions from schema view', () => {
|
||||||
|
cy.fixture('Test_workflow_3.json').then((data) => {
|
||||||
|
cy.get('body').paste(JSON.stringify(data));
|
||||||
|
});
|
||||||
|
|
||||||
|
canvasNode.actions.openNode('Set');
|
||||||
|
ndv.actions.clearParameterInput('value');
|
||||||
|
cy.get('body').type('{esc}');
|
||||||
|
|
||||||
|
ndv.getters.inputDataContainer()
|
||||||
|
.should('exist')
|
||||||
|
.find('span').contains('count')
|
||||||
|
.realMouseDown();
|
||||||
|
|
||||||
|
|
||||||
|
ndv.actions.mapToParameter('value');
|
||||||
|
ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.input[0].count }}');
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('include.text', '0');
|
||||||
|
|
||||||
|
ndv.getters.inputDataContainer()
|
||||||
|
.find('span').contains('input')
|
||||||
|
.realMouseDown();
|
||||||
|
|
||||||
|
ndv.actions.mapToParameter('value');
|
||||||
|
ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.input[0].count }} {{ $json.input }}');
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('include.text', '0 [object Object]');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('maps expressions from previous nodes', () => {
|
||||||
|
cy.createFixtureWorkflow('Test_workflow_3.json', `My test workflow`);
|
||||||
|
canvasNode.actions.openNode('Set1');
|
||||||
|
|
||||||
|
ndv.actions.selectInputNode('Schedule Trigger');
|
||||||
|
|
||||||
|
ndv.getters.inputDataContainer()
|
||||||
|
.find('span').contains('count')
|
||||||
|
.realMouseDown();
|
||||||
|
|
||||||
|
ndv.actions.mapToParameter('value');
|
||||||
|
ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $node["Schedule Trigger"].json.input[0].count }}');
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('not.exist');
|
||||||
|
|
||||||
|
ndv.actions.switchInputMode('Table');
|
||||||
|
ndv.actions.mapDataFromHeader(1, 'value');
|
||||||
|
ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $node["Schedule Trigger"].json.input[0].count }} {{ $node["Schedule Trigger"].json.input }}');
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('not.exist');
|
||||||
|
|
||||||
|
ndv.actions.selectInputNode('Set');
|
||||||
|
|
||||||
|
ndv.actions.executePrevious();
|
||||||
|
ndv.getters.executingLoader().should('not.exist');
|
||||||
|
ndv.getters.inputDataContainer().should('exist');
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('include.text', '0 [object Object]');
|
||||||
|
|
||||||
|
ndv.getters.inputTbodyCell(2, 0).realHover();
|
||||||
|
ndv.getters.parameterExpressionPreview('value')
|
||||||
|
.should('include.text', '1 [object Object]');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('maps keys to path', () => {
|
||||||
|
workflowPage.actions.addInitialNodeToCanvas('Manual Trigger', {keepNdvOpen: true});
|
||||||
|
|
||||||
|
ndv.actions.setPinnedData([
|
||||||
|
{
|
||||||
|
input: [
|
||||||
|
{
|
||||||
|
"hello.world": {
|
||||||
|
"my count": 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: [
|
||||||
|
{
|
||||||
|
"hello.world": {
|
||||||
|
"my count": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
ndv.actions.close();
|
||||||
|
|
||||||
|
workflowPage.actions.addNodeToCanvas('Item Lists');
|
||||||
|
canvasNode.actions.openNode('Item Lists');
|
||||||
|
|
||||||
|
ndv.getters.parameterInput('operation')
|
||||||
|
.click()
|
||||||
|
.find('li').contains('Sort')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
ndv.getters.nodeParameters().find('button').contains('Add Field To Sort By').click();
|
||||||
|
|
||||||
|
ndv.getters.inputDataContainer()
|
||||||
|
.find('span').contains('my count')
|
||||||
|
.realMouseDown();
|
||||||
|
|
||||||
|
ndv.actions.mapToParameter('fieldName');
|
||||||
|
|
||||||
|
ndv.getters.inlineExpressionEditorInput().should('have.length', 0);
|
||||||
|
ndv.getters.parameterInput('fieldName')
|
||||||
|
.find('input').should('have.value', 'input[0]["hello.world"]["my count"]');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
import { WorkflowPage, WorkflowsPage, NDV, CredentialsModal } from '../pages';
|
import { WorkflowPage, NDV, CredentialsModal } from '../pages';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { cowBase64 } from '../support/binaryTestFiles';
|
import { cowBase64 } from '../support/binaryTestFiles';
|
||||||
|
|
||||||
const workflowsPage = new WorkflowsPage();
|
|
||||||
const workflowPage = new WorkflowPage();
|
const workflowPage = new WorkflowPage();
|
||||||
const ndv = new NDV();
|
const ndv = new NDV();
|
||||||
const credentialsModal = new CredentialsModal();
|
const credentialsModal = new CredentialsModal();
|
||||||
|
|
||||||
const webhookWorkflowName = 'Webhook Workflow';
|
|
||||||
const waitForWebhook = 500;
|
const waitForWebhook = 500;
|
||||||
|
|
||||||
interface SimpleWebhookCallOptions {
|
interface SimpleWebhookCallOptions {
|
||||||
|
@ -31,10 +29,6 @@ const simpleWebhookCall = (options: SimpleWebhookCallOptions) => {
|
||||||
executeNow = true,
|
executeNow = true,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
cy.visit(workflowsPage.url);
|
|
||||||
|
|
||||||
workflowsPage.actions.createWorkflowFromCard();
|
|
||||||
workflowPage.actions.renameWorkflow(webhookWorkflowName);
|
|
||||||
workflowPage.actions.addInitialNodeToCanvas('Webhook');
|
workflowPage.actions.addInitialNodeToCanvas('Webhook');
|
||||||
workflowPage.actions.openNode('Webhook');
|
workflowPage.actions.openNode('Webhook');
|
||||||
|
|
||||||
|
@ -97,14 +91,15 @@ const simpleWebhookCall = (options: SimpleWebhookCallOptions) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Webhook Trigger node', async () => {
|
describe('Webhook Trigger node', async () => {
|
||||||
before(() => {
|
beforeEach(() => {
|
||||||
cy.resetAll();
|
cy.resetAll();
|
||||||
cy.skipSetup();
|
cy.skipSetup();
|
||||||
});
|
workflowPage.actions.visit();
|
||||||
|
cy.waitForLoad();
|
||||||
|
|
||||||
afterEach(() => {
|
cy.window()
|
||||||
cy.visit(workflowsPage.url);
|
// @ts-ignore
|
||||||
workflowsPage.actions.deleteWorkFlow(webhookWorkflowName);
|
.then(win => win.onBeforeUnload && win.removeEventListener('beforeunload', win.onBeforeUnload));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should listen for a GET request', () => {
|
it('should listen for a GET request', () => {
|
||||||
|
|
121
cypress/fixtures/Test_workflow_3.json
Normal file
121
cypress/fixtures/Test_workflow_3.json
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
{
|
||||||
|
"name": "My workflow",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"rule": {
|
||||||
|
"interval": [
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "0f7d87ee-19c6-4576-bdff-1f3c4739392c",
|
||||||
|
"name": "Schedule Trigger",
|
||||||
|
"type": "n8n-nodes-base.scheduleTrigger",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
720,
|
||||||
|
300
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"values": {
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "other",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"id": "2dfc690a-95cf-48c2-85a6-2b3bb8cd1d1d",
|
||||||
|
"name": "Set",
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
920,
|
||||||
|
300
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9bee04af-1bfc-4be2-a704-e975cb887ced",
|
||||||
|
"name": "Set1",
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
1120,
|
||||||
|
300
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"values": {
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "other",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pinData": {
|
||||||
|
"Schedule Trigger": [
|
||||||
|
{
|
||||||
|
"json": {
|
||||||
|
"input": [
|
||||||
|
{
|
||||||
|
"count": 0,
|
||||||
|
"with space": "!!",
|
||||||
|
"with.dot": "!!",
|
||||||
|
"with\"quotes": "!!"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"json": {
|
||||||
|
"input": [
|
||||||
|
{
|
||||||
|
"count": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"connections": {
|
||||||
|
"Schedule Trigger": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Set",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Set": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Set1",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"active": false,
|
||||||
|
"settings": {},
|
||||||
|
"versionId": "c26af749-dacb-45ef-8071-98aba8688075",
|
||||||
|
"id": "1",
|
||||||
|
"meta": {
|
||||||
|
"instanceId": "fe45a93dd232270eb40d3ba1f7907ad3935bbd72ad5e4ee09ff61e96674f9aef"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ export class CanvasNode extends BasePage {
|
||||||
|
|
||||||
actions = {
|
actions = {
|
||||||
openNode: (nodeName: string) => {
|
openNode: (nodeName: string) => {
|
||||||
this.getters.nodeByName(nodeName).dblclick();
|
this.getters.nodeByName(nodeName).eq(0).dblclick();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ export class NDV extends BasePage {
|
||||||
inputOption: () => cy.getByTestId('ndv-input-option'),
|
inputOption: () => cy.getByTestId('ndv-input-option'),
|
||||||
inputPanel: () => cy.getByTestId('ndv-input-panel'),
|
inputPanel: () => cy.getByTestId('ndv-input-panel'),
|
||||||
outputPanel: () => cy.getByTestId('output-panel'),
|
outputPanel: () => cy.getByTestId('output-panel'),
|
||||||
|
executingLoader: () => cy.getByTestId('ndv-executing'),
|
||||||
inputDataContainer: () => this.getters.inputPanel().findChildByTestId('ndv-data-container'),
|
inputDataContainer: () => this.getters.inputPanel().findChildByTestId('ndv-data-container'),
|
||||||
inputDisplayMode: () => this.getters.inputPanel().getByTestId('ndv-run-data-display-mode'),
|
inputDisplayMode: () => this.getters.inputPanel().getByTestId('ndv-run-data-display-mode'),
|
||||||
outputDataContainer: () => this.getters.outputPanel().findChildByTestId('ndv-data-container'),
|
outputDataContainer: () => this.getters.outputPanel().findChildByTestId('ndv-data-container'),
|
||||||
|
@ -24,18 +25,18 @@ export class NDV extends BasePage {
|
||||||
outputTableHeaders: () => this.getters.outputDataContainer().find('table thead th'),
|
outputTableHeaders: () => this.getters.outputDataContainer().find('table thead th'),
|
||||||
outputTableRow: (row: number) => this.getters.outputTableRows().eq(row),
|
outputTableRow: (row: number) => this.getters.outputTableRows().eq(row),
|
||||||
outputTbodyCell: (row: number, col: number) => this.getters.outputTableRow(row).find('td').eq(col),
|
outputTbodyCell: (row: number, col: number) => this.getters.outputTableRow(row).find('td').eq(col),
|
||||||
inputTableRows: () => this.getters.outputDataContainer().find('table tr'),
|
inputTableRows: () => this.getters.inputDataContainer().find('table tr'),
|
||||||
inputTableHeaders: () => this.getters.outputDataContainer().find('table thead th'),
|
inputTableHeaders: () => this.getters.inputDataContainer().find('table thead th'),
|
||||||
inputTableRow: (row: number) => this.getters.outputTableRows().eq(row),
|
inputTableRow: (row: number) => this.getters.inputTableRows().eq(row),
|
||||||
inputTbodyCell: (row: number, col: number) => this.getters.outputTableRow(row).find('td').eq(col),
|
inputTbodyCell: (row: number, col: number) => this.getters.inputTableRow(row).find('td').eq(col),
|
||||||
inlineExpressionEditorInput: () => cy.getByTestId('inline-expression-editor-input'),
|
inlineExpressionEditorInput: () => cy.getByTestId('inline-expression-editor-input'),
|
||||||
nodeParameters: () => cy.getByTestId('node-parameters'),
|
nodeParameters: () => cy.getByTestId('node-parameters'),
|
||||||
parameterInput: (parameterName: string) => cy.getByTestId(`parameter-input-${parameterName}`),
|
parameterInput: (parameterName: string) => cy.getByTestId(`parameter-input-${parameterName}`),
|
||||||
|
parameterExpressionPreview: (parameterName: string) => this.getters.nodeParameters().find(`[data-test-id="parameter-input-${parameterName}"] + [data-test-id="parameter-expression-preview"]`),
|
||||||
nodeNameContainer: () => cy.getByTestId('node-title-container'),
|
nodeNameContainer: () => cy.getByTestId('node-title-container'),
|
||||||
nodeRenameInput: () => cy.getByTestId('node-rename-input'),
|
nodeRenameInput: () => cy.getByTestId('node-rename-input'),
|
||||||
executePrevious: () => cy.getByTestId('execute-previous-node'),
|
executePrevious: () => cy.getByTestId('execute-previous-node'),
|
||||||
httpRequestNotice: () => cy.getByTestId('node-parameters-http-notice'),
|
httpRequestNotice: () => cy.getByTestId('node-parameters-http-notice'),
|
||||||
inlineExpressionEditorInput: () => cy.getByTestId('inline-expression-editor-input'),
|
|
||||||
nthParam: (n: number) => cy.getByTestId('node-parameters').find('.parameter-item').eq(n),
|
nthParam: (n: number) => cy.getByTestId('node-parameters').find('.parameter-item').eq(n),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,6 +47,9 @@ export class NDV extends BasePage {
|
||||||
editPinnedData: () => {
|
editPinnedData: () => {
|
||||||
this.getters.editPinnedDataButton().click();
|
this.getters.editPinnedDataButton().click();
|
||||||
},
|
},
|
||||||
|
savePinnedData: () => {
|
||||||
|
this.getters.savePinnedDataButton().click();
|
||||||
|
},
|
||||||
execute: () => {
|
execute: () => {
|
||||||
this.getters.nodeExecuteButton().first().click();
|
this.getters.nodeExecuteButton().first().click();
|
||||||
},
|
},
|
||||||
|
@ -64,7 +68,10 @@ export class NDV extends BasePage {
|
||||||
editor.type(`{selectall}{backspace}`);
|
editor.type(`{selectall}{backspace}`);
|
||||||
editor.type(JSON.stringify(data).replace(new RegExp('{', 'g'), '{{}'));
|
editor.type(JSON.stringify(data).replace(new RegExp('{', 'g'), '{{}'));
|
||||||
|
|
||||||
this.getters.savePinnedDataButton().click();
|
this.actions.savePinnedData();
|
||||||
|
},
|
||||||
|
clearParameterInput: (parameterName: string) => {
|
||||||
|
this.getters.parameterInput(parameterName).type(`{selectall}{backspace}`);
|
||||||
},
|
},
|
||||||
typeIntoParameterInput: (parameterName: string, content: string) => {
|
typeIntoParameterInput: (parameterName: string, content: string) => {
|
||||||
this.getters.parameterInput(parameterName).type(content);
|
this.getters.parameterInput(parameterName).type(content);
|
||||||
|
@ -92,11 +99,23 @@ export class NDV extends BasePage {
|
||||||
const droppable = `[data-test-id="parameter-input-${parameterName}"]`;
|
const droppable = `[data-test-id="parameter-input-${parameterName}"]`;
|
||||||
cy.draganddrop(draggable, droppable);
|
cy.draganddrop(draggable, droppable);
|
||||||
},
|
},
|
||||||
|
mapToParameter: (parameterName: string) => {
|
||||||
|
const droppable = `[data-test-id="parameter-input-${parameterName}"]`;
|
||||||
|
cy.draganddrop('', droppable);
|
||||||
|
},
|
||||||
switchInputMode: (type: 'Schema' | 'Table' | 'JSON' | 'Binary') => {
|
switchInputMode: (type: 'Schema' | 'Table' | 'JSON' | 'Binary') => {
|
||||||
this.getters.inputDisplayMode().find('label').contains(type).click();
|
this.getters.inputDisplayMode().find('label').contains(type).click({force: true});
|
||||||
},
|
},
|
||||||
switchOutputMode: (type: 'Schema' | 'Table' | 'JSON' | 'Binary') => {
|
switchOutputMode: (type: 'Schema' | 'Table' | 'JSON' | 'Binary') => {
|
||||||
this.getters.outputDisplayMode().find('label').contains(type).click();
|
this.getters.outputDisplayMode().find('label').contains(type).click({force: true});
|
||||||
|
},
|
||||||
|
selectInputNode: (nodeName: string) => {
|
||||||
|
this.getters.inputSelect().find('.el-select').click();
|
||||||
|
this.getters.inputOption().contains(nodeName).click();
|
||||||
|
},
|
||||||
|
addDefaultPinnedData: () => {
|
||||||
|
this.actions.editPinnedData();
|
||||||
|
this.actions.savePinnedData();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,9 @@ Cypress.Commands.add('drag', (selector, pos) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('draganddrop', (draggableSelector, droppableSelector) => {
|
Cypress.Commands.add('draganddrop', (draggableSelector, droppableSelector) => {
|
||||||
cy.get(draggableSelector).should('exist');
|
if (draggableSelector) {
|
||||||
|
cy.get(draggableSelector).should('exist');
|
||||||
|
}
|
||||||
cy.get(droppableSelector).should('exist');
|
cy.get(droppableSelector).should('exist');
|
||||||
|
|
||||||
cy.get(droppableSelector)
|
cy.get(droppableSelector)
|
||||||
|
@ -254,12 +256,16 @@ Cypress.Commands.add('draganddrop', (draggableSelector, droppableSelector) => {
|
||||||
const pageX = coords.left + coords.width / 2;
|
const pageX = coords.left + coords.width / 2;
|
||||||
const pageY = coords.top + coords.height / 2;
|
const pageY = coords.top + coords.height / 2;
|
||||||
|
|
||||||
// We can't use realMouseDown here because it hangs headless run
|
if (draggableSelector) {
|
||||||
cy.get(draggableSelector).trigger('mousedown');
|
// We can't use realMouseDown here because it hangs headless run
|
||||||
|
cy.get(draggableSelector).trigger('mousedown');
|
||||||
|
}
|
||||||
// We don't chain these commands to make sure cy.get is re-trying correctly
|
// We don't chain these commands to make sure cy.get is re-trying correctly
|
||||||
cy.get(droppableSelector).realMouseMove(pageX, pageY);
|
cy.get(droppableSelector).realMouseMove(pageX, pageY);
|
||||||
cy.get(droppableSelector).realHover();
|
cy.get(droppableSelector).realHover();
|
||||||
cy.get(droppableSelector).realMouseUp();
|
cy.get(droppableSelector).realMouseUp();
|
||||||
cy.get(draggableSelector).realMouseUp();
|
if (draggableSelector) {
|
||||||
|
cy.get(draggableSelector).realMouseUp();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -48,7 +48,7 @@ declare global {
|
||||||
readClipboard(): Chainable<string>;
|
readClipboard(): Chainable<string>;
|
||||||
paste(pastePayload: string): void;
|
paste(pastePayload: string): void;
|
||||||
drag(selector: string, target: [number, number]): void;
|
drag(selector: string, target: [number, number]): void;
|
||||||
draganddrop(selector: string, target: string): void;
|
draganddrop(draggableSelector: string, droppableSelector: string): void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,16 +16,17 @@
|
||||||
:isForCredential="isForCredential"
|
:isForCredential="isForCredential"
|
||||||
:eventSource="eventSource"
|
:eventSource="eventSource"
|
||||||
:expressionEvaluated="expressionValueComputed"
|
:expressionEvaluated="expressionValueComputed"
|
||||||
|
:data-test-id="`parameter-input-${parameter.name}`"
|
||||||
@focus="onFocus"
|
@focus="onFocus"
|
||||||
@blur="onBlur"
|
@blur="onBlur"
|
||||||
@drop="onDrop"
|
@drop="onDrop"
|
||||||
@textInput="onTextInput"
|
@textInput="onTextInput"
|
||||||
@valueChanged="onValueChanged"
|
@valueChanged="onValueChanged"
|
||||||
:data-test-id="`parameter-input-${parameter.name}`"
|
|
||||||
/>
|
/>
|
||||||
<input-hint
|
<input-hint
|
||||||
v-if="expressionOutput"
|
v-if="expressionOutput"
|
||||||
:class="$style.hint"
|
:class="$style.hint"
|
||||||
|
data-test-id="parameter-expression-preview"
|
||||||
:highlight="!!(expressionOutput && targetItem)"
|
:highlight="!!(expressionOutput && targetItem)"
|
||||||
:hint="expressionOutput"
|
:hint="expressionOutput"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -2536,7 +2536,10 @@ export default mixins(
|
||||||
this.uiStore.nodeViewInitialized = true;
|
this.uiStore.nodeViewInitialized = true;
|
||||||
document.addEventListener('keydown', this.keyDown);
|
document.addEventListener('keydown', this.keyDown);
|
||||||
document.addEventListener('keyup', this.keyUp);
|
document.addEventListener('keyup', this.keyUp);
|
||||||
window.addEventListener('beforeunload', (e) => {
|
|
||||||
|
// allow to be overriden in e2e tests
|
||||||
|
// @ts-ignore
|
||||||
|
window.onBeforeUnload = (e) => {
|
||||||
if (this.isDemo) {
|
if (this.isDemo) {
|
||||||
return;
|
return;
|
||||||
} else if (this.uiStore.stateIsDirty) {
|
} else if (this.uiStore.stateIsDirty) {
|
||||||
|
@ -2549,7 +2552,8 @@ export default mixins(
|
||||||
this.startLoading(this.$locale.baseText('nodeView.redirecting'));
|
this.startLoading(this.$locale.baseText('nodeView.redirecting'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
window.addEventListener('beforeunload', window.onBeforeUnload);
|
||||||
},
|
},
|
||||||
getOutputEndpointUUID(nodeName: string, index: number): string | null {
|
getOutputEndpointUUID(nodeName: string, index: number): string | null {
|
||||||
const node = this.workflowsStore.getNodeByName(nodeName);
|
const node = this.workflowsStore.getNodeByName(nodeName);
|
||||||
|
|
Loading…
Reference in a new issue