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

View file

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

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 { 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;

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

View file

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

View file

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

View file

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

View file

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