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:
Mutasem Aldmour 2023-02-09 17:59:01 +03:00 committed by GitHub
parent 00befbc75a
commit b8980f6118
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 393 additions and 68 deletions

View file

@ -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);
}); });
}); });

View file

@ -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"]');
});
}); });

View file

@ -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', () => {

View 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": []
}

View file

@ -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();
}, },
}; };
} }

View file

@ -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();
}, },
}; };
} }

View file

@ -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();
}
}); });
}); });

View file

@ -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;
} }
} }
} }

View file

@ -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"
/> />

View file

@ -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);