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();
|
||||
|
||||
describe('Data transformation expressions', () => {
|
||||
before(() => {
|
||||
beforeEach(() => {
|
||||
cy.resetAll();
|
||||
cy.skipSetup();
|
||||
wf.actions.visit();
|
||||
cy.waitForLoad();
|
||||
|
||||
cy.window()
|
||||
// @ts-ignore
|
||||
.then(win => win.onBeforeUnload && win.removeEventListener('beforeunload', win.onBeforeUnload));
|
||||
});
|
||||
|
||||
it('$json + native string methods', () => {
|
||||
wf.actions.visit();
|
||||
|
||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||
ndv.actions.setPinnedData([{ myStr: 'Monday' }]);
|
||||
ndv.actions.close();
|
||||
|
@ -23,12 +26,10 @@ describe('Data transformation expressions', () => {
|
|||
|
||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||
ndv.actions.execute();
|
||||
ndv.getters.outputDataContainer().contains(output).should('be.visible');
|
||||
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||
});
|
||||
|
||||
it('$json + n8n string methods', () => {
|
||||
wf.actions.visit();
|
||||
|
||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||
ndv.actions.setPinnedData([{ myStr: 'hello@n8n.io is an email' }]);
|
||||
ndv.actions.close();
|
||||
|
@ -39,12 +40,10 @@ describe('Data transformation expressions', () => {
|
|||
|
||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||
ndv.actions.execute();
|
||||
ndv.getters.outputDataContainer().contains(output).should('be.visible');
|
||||
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||
});
|
||||
|
||||
it('$json + native numeric methods', () => {
|
||||
wf.actions.visit();
|
||||
|
||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||
ndv.actions.setPinnedData([{ myNum: 9.123 }]);
|
||||
ndv.actions.close();
|
||||
|
@ -55,12 +54,10 @@ describe('Data transformation expressions', () => {
|
|||
|
||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||
ndv.actions.execute();
|
||||
ndv.getters.outputDataContainer().contains(output).should('be.visible');
|
||||
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||
});
|
||||
|
||||
it('$json + n8n numeric methods', () => {
|
||||
wf.actions.visit();
|
||||
|
||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||
ndv.actions.setPinnedData([{ myStr: 'hello@n8n.io is an email' }]);
|
||||
ndv.actions.close();
|
||||
|
@ -71,12 +68,10 @@ describe('Data transformation expressions', () => {
|
|||
|
||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||
ndv.actions.execute();
|
||||
ndv.getters.outputDataContainer().contains(output).should('be.visible');
|
||||
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||
});
|
||||
|
||||
it('$json + native array methods', () => {
|
||||
wf.actions.visit();
|
||||
|
||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||
ndv.actions.setPinnedData([{ myArr: [1, 2, 3] }]);
|
||||
ndv.actions.close();
|
||||
|
@ -87,12 +82,10 @@ describe('Data transformation expressions', () => {
|
|||
|
||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||
ndv.actions.execute();
|
||||
ndv.getters.outputDataContainer().contains(output).should('be.visible');
|
||||
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||
});
|
||||
|
||||
it('$json + n8n array methods', () => {
|
||||
wf.actions.visit();
|
||||
|
||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||
ndv.actions.setPinnedData([{ myArr: [1, 2, 3] }]);
|
||||
ndv.actions.close();
|
||||
|
@ -103,7 +96,7 @@ describe('Data transformation expressions', () => {
|
|||
|
||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||
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();
|
||||
|
||||
describe('Data mapping', () => {
|
||||
before(() => {
|
||||
beforeEach(() => {
|
||||
cy.resetAll();
|
||||
cy.skipSetup();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
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.get('body').paste(JSON.stringify(data));
|
||||
});
|
||||
|
@ -34,4 +36,188 @@ describe('Data mapping', () => {
|
|||
ndv.actions.mapDataFromHeader(2, 'value');
|
||||
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 { cowBase64 } from '../support/binaryTestFiles';
|
||||
|
||||
const workflowsPage = new WorkflowsPage();
|
||||
const workflowPage = new WorkflowPage();
|
||||
const ndv = new NDV();
|
||||
const credentialsModal = new CredentialsModal();
|
||||
|
||||
const webhookWorkflowName = 'Webhook Workflow';
|
||||
const waitForWebhook = 500;
|
||||
|
||||
interface SimpleWebhookCallOptions {
|
||||
|
@ -21,7 +19,7 @@ interface SimpleWebhookCallOptions {
|
|||
}
|
||||
|
||||
const simpleWebhookCall = (options: SimpleWebhookCallOptions) => {
|
||||
const {
|
||||
const {
|
||||
authentication,
|
||||
method,
|
||||
webhookPath,
|
||||
|
@ -31,10 +29,6 @@ const simpleWebhookCall = (options: SimpleWebhookCallOptions) => {
|
|||
executeNow = true,
|
||||
} = options;
|
||||
|
||||
cy.visit(workflowsPage.url);
|
||||
|
||||
workflowsPage.actions.createWorkflowFromCard();
|
||||
workflowPage.actions.renameWorkflow(webhookWorkflowName);
|
||||
workflowPage.actions.addInitialNodeToCanvas('Webhook');
|
||||
workflowPage.actions.openNode('Webhook');
|
||||
|
||||
|
@ -49,7 +43,7 @@ const simpleWebhookCall = (options: SimpleWebhookCallOptions) => {
|
|||
.find('input')
|
||||
.clear()
|
||||
.type(webhookPath);
|
||||
|
||||
|
||||
if (authentication) {
|
||||
cy.getByTestId('parameter-input-authentication').click();
|
||||
cy.getByTestId('parameter-input-authentication')
|
||||
|
@ -66,7 +60,7 @@ const simpleWebhookCall = (options: SimpleWebhookCallOptions) => {
|
|||
.clear()
|
||||
.type(responseCode.toString());
|
||||
}
|
||||
|
||||
|
||||
if (respondWith) {
|
||||
cy.getByTestId('parameter-input-responseMode').click();
|
||||
cy.getByTestId('parameter-input-responseMode')
|
||||
|
@ -85,7 +79,7 @@ const simpleWebhookCall = (options: SimpleWebhookCallOptions) => {
|
|||
.click();
|
||||
}
|
||||
|
||||
if (executeNow) {
|
||||
if (executeNow) {
|
||||
ndv.actions.execute();
|
||||
cy.wait(waitForWebhook);
|
||||
|
||||
|
@ -97,14 +91,15 @@ const simpleWebhookCall = (options: SimpleWebhookCallOptions) => {
|
|||
};
|
||||
|
||||
describe('Webhook Trigger node', async () => {
|
||||
before(() => {
|
||||
beforeEach(() => {
|
||||
cy.resetAll();
|
||||
cy.skipSetup();
|
||||
});
|
||||
workflowPage.actions.visit();
|
||||
cy.waitForLoad();
|
||||
|
||||
afterEach(() => {
|
||||
cy.visit(workflowsPage.url);
|
||||
workflowsPage.actions.deleteWorkFlow(webhookWorkflowName);
|
||||
cy.window()
|
||||
// @ts-ignore
|
||||
.then(win => win.onBeforeUnload && win.removeEventListener('beforeunload', win.onBeforeUnload));
|
||||
});
|
||||
|
||||
it('should listen for a GET request', () => {
|
||||
|
@ -138,7 +133,7 @@ describe('Webhook Trigger node', async () => {
|
|||
});
|
||||
|
||||
ndv.getters.backToCanvas().click();
|
||||
|
||||
|
||||
workflowPage.actions.addNodeToCanvas('Set');
|
||||
workflowPage.actions.openNode('Set');
|
||||
cy.get('.add-option').click();
|
||||
|
@ -146,12 +141,12 @@ describe('Webhook Trigger node', async () => {
|
|||
cy.get('.fixed-collection-parameter').getByTestId('parameter-input-name').clear().type('MyValue');
|
||||
cy.get('.fixed-collection-parameter').getByTestId('parameter-input-value').clear().type('1234');
|
||||
ndv.getters.backToCanvas().click();
|
||||
|
||||
|
||||
workflowPage.actions.addNodeToCanvas('Respond to Webhook');
|
||||
|
||||
workflowPage.actions.executeWorkflow();
|
||||
cy.wait(waitForWebhook);
|
||||
|
||||
|
||||
cy.request('GET', '/webhook-test/'+ webhookPath).then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body.MyValue).to.eq(1234);
|
||||
|
@ -169,7 +164,7 @@ describe('Webhook Trigger node', async () => {
|
|||
|
||||
ndv.actions.execute();
|
||||
cy.wait(waitForWebhook);
|
||||
|
||||
|
||||
cy.request('GET', '/webhook-test/'+ webhookPath).then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
});
|
||||
|
@ -184,7 +179,7 @@ describe('Webhook Trigger node', async () => {
|
|||
respondWith: 'Last Node',
|
||||
});
|
||||
ndv.getters.backToCanvas().click();
|
||||
|
||||
|
||||
workflowPage.actions.addNodeToCanvas('Set');
|
||||
workflowPage.actions.openNode('Set');
|
||||
cy.get('.add-option').click();
|
||||
|
@ -192,10 +187,10 @@ describe('Webhook Trigger node', async () => {
|
|||
cy.get('.fixed-collection-parameter').getByTestId('parameter-input-name').clear().type('MyValue');
|
||||
cy.get('.fixed-collection-parameter').getByTestId('parameter-input-value').clear().type('1234');
|
||||
ndv.getters.backToCanvas().click();
|
||||
|
||||
|
||||
workflowPage.actions.executeWorkflow();
|
||||
cy.wait(waitForWebhook);
|
||||
|
||||
|
||||
cy.request('GET', '/webhook-test/'+ webhookPath).then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body.MyValue).to.eq(1234);
|
||||
|
@ -212,7 +207,7 @@ describe('Webhook Trigger node', async () => {
|
|||
responseData: 'First Entry Binary',
|
||||
});
|
||||
ndv.getters.backToCanvas().click();
|
||||
|
||||
|
||||
workflowPage.actions.addNodeToCanvas('Set');
|
||||
workflowPage.actions.openNode('Set');
|
||||
cy.get('.add-option').click();
|
||||
|
@ -220,7 +215,7 @@ describe('Webhook Trigger node', async () => {
|
|||
cy.get('.fixed-collection-parameter').getByTestId('parameter-input-name').clear().type('data');
|
||||
cy.get('.fixed-collection-parameter').getByTestId('parameter-input-value').clear().find('input').invoke('val', cowBase64).trigger('blur');
|
||||
ndv.getters.backToCanvas().click();
|
||||
|
||||
|
||||
|
||||
workflowPage.actions.addNodeToCanvas('Move Binary Data');
|
||||
workflowPage.actions.zoomToFit();
|
||||
|
@ -233,10 +228,10 @@ describe('Webhook Trigger node', async () => {
|
|||
.contains('JSON to Binary')
|
||||
.click();
|
||||
ndv.getters.backToCanvas().click();
|
||||
|
||||
|
||||
workflowPage.actions.executeWorkflow();
|
||||
cy.wait(waitForWebhook);
|
||||
|
||||
|
||||
cy.request('GET', '/webhook-test/'+ webhookPath).then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(Object.keys(response.body).includes('data')).to.be.true;
|
||||
|
|
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 = {
|
||||
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'),
|
||||
inputPanel: () => cy.getByTestId('ndv-input-panel'),
|
||||
outputPanel: () => cy.getByTestId('output-panel'),
|
||||
executingLoader: () => cy.getByTestId('ndv-executing'),
|
||||
inputDataContainer: () => this.getters.inputPanel().findChildByTestId('ndv-data-container'),
|
||||
inputDisplayMode: () => this.getters.inputPanel().getByTestId('ndv-run-data-display-mode'),
|
||||
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'),
|
||||
outputTableRow: (row: number) => this.getters.outputTableRows().eq(row),
|
||||
outputTbodyCell: (row: number, col: number) => this.getters.outputTableRow(row).find('td').eq(col),
|
||||
inputTableRows: () => this.getters.outputDataContainer().find('table tr'),
|
||||
inputTableHeaders: () => this.getters.outputDataContainer().find('table thead th'),
|
||||
inputTableRow: (row: number) => this.getters.outputTableRows().eq(row),
|
||||
inputTbodyCell: (row: number, col: number) => this.getters.outputTableRow(row).find('td').eq(col),
|
||||
inputTableRows: () => this.getters.inputDataContainer().find('table tr'),
|
||||
inputTableHeaders: () => this.getters.inputDataContainer().find('table thead th'),
|
||||
inputTableRow: (row: number) => this.getters.inputTableRows().eq(row),
|
||||
inputTbodyCell: (row: number, col: number) => this.getters.inputTableRow(row).find('td').eq(col),
|
||||
inlineExpressionEditorInput: () => cy.getByTestId('inline-expression-editor-input'),
|
||||
nodeParameters: () => cy.getByTestId('node-parameters'),
|
||||
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'),
|
||||
nodeRenameInput: () => cy.getByTestId('node-rename-input'),
|
||||
executePrevious: () => cy.getByTestId('execute-previous-node'),
|
||||
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),
|
||||
};
|
||||
|
||||
|
@ -46,6 +47,9 @@ export class NDV extends BasePage {
|
|||
editPinnedData: () => {
|
||||
this.getters.editPinnedDataButton().click();
|
||||
},
|
||||
savePinnedData: () => {
|
||||
this.getters.savePinnedDataButton().click();
|
||||
},
|
||||
execute: () => {
|
||||
this.getters.nodeExecuteButton().first().click();
|
||||
},
|
||||
|
@ -64,7 +68,10 @@ export class NDV extends BasePage {
|
|||
editor.type(`{selectall}{backspace}`);
|
||||
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) => {
|
||||
this.getters.parameterInput(parameterName).type(content);
|
||||
|
@ -92,11 +99,23 @@ export class NDV extends BasePage {
|
|||
const droppable = `[data-test-id="parameter-input-${parameterName}"]`;
|
||||
cy.draganddrop(draggable, droppable);
|
||||
},
|
||||
mapToParameter: (parameterName: string) => {
|
||||
const droppable = `[data-test-id="parameter-input-${parameterName}"]`;
|
||||
cy.draganddrop('', droppable);
|
||||
},
|
||||
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') => {
|
||||
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) => {
|
||||
cy.get(draggableSelector).should('exist');
|
||||
if (draggableSelector) {
|
||||
cy.get(draggableSelector).should('exist');
|
||||
}
|
||||
cy.get(droppableSelector).should('exist');
|
||||
|
||||
cy.get(droppableSelector)
|
||||
|
@ -254,12 +256,16 @@ Cypress.Commands.add('draganddrop', (draggableSelector, droppableSelector) => {
|
|||
const pageX = coords.left + coords.width / 2;
|
||||
const pageY = coords.top + coords.height / 2;
|
||||
|
||||
// We can't use realMouseDown here because it hangs headless run
|
||||
cy.get(draggableSelector).trigger('mousedown');
|
||||
if (draggableSelector) {
|
||||
// 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
|
||||
cy.get(droppableSelector).realMouseMove(pageX, pageY);
|
||||
cy.get(droppableSelector).realHover();
|
||||
cy.get(droppableSelector).realMouseUp();
|
||||
cy.get(draggableSelector).realMouseUp();
|
||||
if (draggableSelector) {
|
||||
cy.get(draggableSelector).realMouseUp();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -48,7 +48,7 @@ declare global {
|
|||
readClipboard(): Chainable<string>;
|
||||
paste(pastePayload: string): 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"
|
||||
:eventSource="eventSource"
|
||||
:expressionEvaluated="expressionValueComputed"
|
||||
:data-test-id="`parameter-input-${parameter.name}`"
|
||||
@focus="onFocus"
|
||||
@blur="onBlur"
|
||||
@drop="onDrop"
|
||||
@textInput="onTextInput"
|
||||
@valueChanged="onValueChanged"
|
||||
:data-test-id="`parameter-input-${parameter.name}`"
|
||||
/>
|
||||
<input-hint
|
||||
v-if="expressionOutput"
|
||||
:class="$style.hint"
|
||||
data-test-id="parameter-expression-preview"
|
||||
:highlight="!!(expressionOutput && targetItem)"
|
||||
:hint="expressionOutput"
|
||||
/>
|
||||
|
|
|
@ -2536,7 +2536,10 @@ export default mixins(
|
|||
this.uiStore.nodeViewInitialized = true;
|
||||
document.addEventListener('keydown', this.keyDown);
|
||||
document.addEventListener('keyup', this.keyUp);
|
||||
window.addEventListener('beforeunload', (e) => {
|
||||
|
||||
// allow to be overriden in e2e tests
|
||||
// @ts-ignore
|
||||
window.onBeforeUnload = (e) => {
|
||||
if (this.isDemo) {
|
||||
return;
|
||||
} else if (this.uiStore.stateIsDirty) {
|
||||
|
@ -2549,7 +2552,8 @@ export default mixins(
|
|||
this.startLoading(this.$locale.baseText('nodeView.redirecting'));
|
||||
return;
|
||||
}
|
||||
});
|
||||
};
|
||||
window.addEventListener('beforeunload', window.onBeforeUnload);
|
||||
},
|
||||
getOutputEndpointUUID(nodeName: string, index: number): string | null {
|
||||
const node = this.workflowsStore.getNodeByName(nodeName);
|
||||
|
|
Loading…
Reference in a new issue