test: Add data mapping test (#5372)

* test: add tests for pinning

* test: add test for value

* test: add pinned data tests

* test: refactor into ndv

* refactor: move to ndv

* refactor: rename node

* test: fix test

* test: fix refactor

* test: remove unused id

* test: update test

* test: chain rename input

* test: refactor invoking text

* test: fix ndv tests

* test: move test id

* test: add tests for mapping

* test: update selectors

* test: add mapping

* test: remove wait

* test: add back line removed by mistake

* test: refactor to support both in/output displays

* test: add display mode switching

* test: fix drop

* chore: clean up change

* refactor: add draganddrop

* fix: fix drag and drop

* test: add mapping test for second value

* test: update text

* test: update param
This commit is contained in:
Mutasem Aldmour 2023-02-07 07:47:37 +03:00 committed by GitHub
parent 9efcf19082
commit db49f052bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 116 additions and 14 deletions

View file

@ -116,7 +116,7 @@ describe('Undo/Redo', () => {
it('should undo/redo moving nodes', () => {
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
cy.drag('[data-test-id="canvas-node"].jtk-drag-selected', 50, 150);
cy.drag('[data-test-id="canvas-node"].jtk-drag-selected', [50, 150]);
WorkflowPage.getters
.canvasNodes()
.last()
@ -148,7 +148,7 @@ describe('Undo/Redo', () => {
it('should undo/redo deleting a connection by moving it away', () => {
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
cy.drag('.rect-input-endpoint.jtk-endpoint-connected', 0, -100);
cy.drag('.rect-input-endpoint.jtk-endpoint-connected', [0, -100]);
WorkflowPage.getters.nodeConnections().should('have.length', 0);
WorkflowPage.actions.hitUndo();
WorkflowPage.getters.nodeConnections().should('have.length', 1);
@ -266,7 +266,7 @@ describe('Undo/Redo', () => {
WorkflowPage.actions.hitDisableNodeShortcut();
// Move first one
WorkflowPage.getters.canvasNodes().first().click();
cy.drag('[data-test-id="canvas-node"].jtk-drag-selected', 50, 150);
cy.drag('[data-test-id="canvas-node"].jtk-drag-selected', [50, 150]);
// Delete the set node
WorkflowPage.getters.canvasNodeByName(SET_NODE_NAME).click().click();
cy.get('body').type('{backspace}');

View file

@ -117,7 +117,7 @@ describe('Canvas Actions', () => {
WorkflowPage.actions.addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
WorkflowPage.actions.zoomToFit();
cy.drag('[data-test-id="canvas-node"].jtk-drag-selected', 50, 150);
cy.drag('[data-test-id="canvas-node"].jtk-drag-selected', [50, 150]);
WorkflowPage.getters
.canvasNodes()
.last()
@ -223,7 +223,7 @@ describe('Canvas Actions', () => {
it('should delete a connection by moving it away from endpoint', () => {
WorkflowPage.actions.addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME);
cy.drag('.rect-input-endpoint.jtk-endpoint-connected', 0, -100);
cy.drag('.rect-input-endpoint.jtk-endpoint-connected', [0, -100]);
WorkflowPage.getters.nodeConnections().should('have.length', 0);
});

View file

@ -0,0 +1,37 @@
import { WorkflowPage, NDV, CanvasNode } from '../pages';
const workflowPage = new WorkflowPage();
const ndv = new NDV();
const canvasNode = new CanvasNode();
describe('Data mapping', () => {
before(() => {
cy.resetAll();
cy.skipSetup();
});
beforeEach(() => {
workflowPage.actions.visit();
});
it('Should be able to map expressions from table header', () => {
cy.fixture('Test_workflow-actions_paste-data.json').then((data) => {
cy.get('body').paste(JSON.stringify(data));
});
canvasNode.actions.openNode('Set');
ndv.actions.executePrevious();
ndv.actions.switchInputMode('Table');
ndv.getters.inputDataContainer().get('table', { timeout: 10000 }).should('exist');
ndv.getters.nodeParameters().find('input[placeholder*="Add Value"]').click();
ndv.getters.nodeParameters().find('.el-select-dropdown__list li:nth-child(3)').should('have.text', 'String').click();
ndv.getters.parameterInput('name').should('have.length', 1).find('input').should('have.value', 'propertyName');
ndv.getters.parameterInput('value').should('have.length', 1).find('input').should('have.value', '');
ndv.actions.mapDataFromHeader(1, 'value');
ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.timestamp }}');
ndv.actions.mapDataFromHeader(2, 'value');
ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.timestamp }} {{ $json["Readable date"] }}');
});
});

View file

@ -42,7 +42,7 @@ describe('NDV', () => {
});
});
ndv.getters.runDataDisplayMode().should('have.length.at.least', 1).and('be.visible');
ndv.getters.outputDisplayMode().should('have.length.at.least', 1).and('be.visible');
});
it('should change input', () => {

View file

@ -0,0 +1,15 @@
import { BasePage } from './base';
export class CanvasNode extends BasePage {
getters = {
nodes: () => cy.getByTestId('canvas-node'),
nodeByName: (nodeName: string) =>
this.getters.nodes().filter(`:contains("${nodeName}")`),
};
actions = {
openNode: (nodeName: string) => {
this.getters.nodeByName(nodeName).dblclick();
},
};
}

View file

@ -8,3 +8,4 @@ export * from './modals';
export * from './settings-users';
export * from './settings-log-streaming';
export * from './ndv';
export * from './canvas-node';

View file

@ -11,8 +11,9 @@ export class NDV extends BasePage {
inputPanel: () => cy.getByTestId('ndv-input-panel'),
outputPanel: () => cy.getByTestId('output-panel'),
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'),
runDataDisplayMode: () => cy.getByTestId('ndv-run-data-display-mode'),
outputDisplayMode: () => this.getters.outputPanel().getByTestId('ndv-run-data-display-mode'),
digital: () => cy.getByTestId('ndv-run-data-display-mode'),
pinDataButton: () => cy.getByTestId('ndv-pin-data'),
editPinnedDataButton: () => cy.getByTestId('ndv-edit-pinned-data'),
@ -22,11 +23,17 @@ export class NDV extends BasePage {
outputTableRows: () => this.getters.outputDataContainer().find('table tr'),
outputTableHeaders: () => this.getters.outputDataContainer().find('table thead th'),
outputTableRow: (row: number) => this.getters.outputTableRows().eq(row),
outputTbodyCell: (row: number, cell: number) =>
this.getters.outputTableRow(row).find('td').eq(cell),
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),
inlineExpressionEditorInput: () => cy.getByTestId('inline-expression-editor-input'),
nodeParameters: () => cy.getByTestId('node-parameters'),
parameterInput: (parameterName: string) => cy.getByTestId(`parameter-input-${parameterName}`),
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'),
};
@ -57,12 +64,33 @@ export class NDV extends BasePage {
this.getters.parameterInput(parameterName).type(content);
},
selectOptionInParameterDropdown: (parameterName: string, content: string) => {
this.getters.parameterInput(parameterName).find('.option-headline').contains(content).click();
this.getters
.parameterInput(parameterName)
.find('.option-headline')
.contains(content)
.click();
},
rename: (newName: string) => {
this.getters.nodeNameContainer().click();
this.getters.nodeRenameInput().should('be.visible').type('{selectall}').type(newName);
this.getters.nodeRenameInput()
.should('be.visible')
.type('{selectall}')
.type(newName);
cy.get('body').type('{enter}');
},
executePrevious: () => {
this.getters.executePrevious().click();
},
mapDataFromHeader: (col: number, parameterName: string) => {
const draggable = `[data-test-id="ndv-input-panel"] [data-test-id="ndv-data-container"] table th:nth-child(${col})`;
const droppable = `[data-test-id="parameter-input-${parameterName}"]`;
cy.draganddrop(draggable, droppable);
},
switchInputMode: (type: 'Schema' | 'Table' | 'JSON' | 'Binary') => {
this.getters.inputDisplayMode().find('label').contains(type).click();
},
switchOutputMode: (type: 'Schema' | 'Table' | 'JSON' | 'Binary') => {
this.getters.outputDisplayMode().find('label').contains(type).click();
},
};
}

View file

@ -173,7 +173,8 @@ Cypress.Commands.add('paste', { prevSubject: true }, (selector, pastePayload) =>
});
});
Cypress.Commands.add('drag', (selector, xDiff, yDiff) => {
Cypress.Commands.add('drag', (selector, pos) => {
const [xDiff, yDiff] = pos;
const element = cy.get(selector);
element.should('exist');
@ -188,3 +189,21 @@ Cypress.Commands.add('drag', (selector, xDiff, yDiff) => {
});
element.trigger('mouseup');
});
Cypress.Commands.add('draganddrop', (draggableSelector, droppableSelector) => {
cy.get(draggableSelector).should('exist');
cy.get(droppableSelector).should('exist');
const droppableEl = Cypress.$(droppableSelector)[0];
const coords = droppableEl.getBoundingClientRect();
const pageX = coords.left + coords.width / 2;
const pageY = coords.top + coords.height / 2;
cy.get(draggableSelector).realMouseDown();
cy.get(droppableSelector).realMouseMove(pageX, pageY)
.realHover()
.realMouseUp();
});

View file

@ -32,7 +32,8 @@ declare global {
grantBrowserPermissions(...permissions: string[]): void;
readClipboard(): Chainable<string>;
paste(pastePayload: string): void;
drag(selector: string, xDiff: number, yDiff: number): void;
drag(selector: string, target: [number, number]): void;
draganddrop(selector: string, target: string): void;
}
}
}

View file

@ -85,6 +85,7 @@
:label="$locale.baseText('ndv.input.noOutputData.executePrevious')"
@execute="onNodeExecute"
telemetrySource="inputs"
data-test-id="execute-previous-node"
/>
</n8n-tooltip>
<n8n-text v-if="!readOnly" tag="div" size="small">

View file

@ -172,7 +172,7 @@
</div>
<div :class="$style['data-container']" ref="dataContainer" data-test-id="ndv-data-container">
<div v-if="isExecuting" :class="$style.center">
<div v-if="isExecuting" :class="$style.center" data-test-id="ndv-executing">
<div :class="$style.spinner"><n8n-spinner type="ring" /></div>
<n8n-text>{{ executingMessage }}</n8n-text>
</div>