mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
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:
parent
9efcf19082
commit
db49f052bc
|
@ -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}');
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
37
cypress/e2e/14-mapping.cy.ts
Normal file
37
cypress/e2e/14-mapping.cy.ts
Normal 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"] }}');
|
||||
});
|
||||
});
|
|
@ -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', () => {
|
||||
|
|
15
cypress/pages/canvas-node.ts
Normal file
15
cypress/pages/canvas-node.ts
Normal 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();
|
||||
},
|
||||
};
|
||||
}
|
|
@ -8,3 +8,4 @@ export * from './modals';
|
|||
export * from './settings-users';
|
||||
export * from './settings-log-streaming';
|
||||
export * from './ndv';
|
||||
export * from './canvas-node';
|
||||
|
|
|
@ -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();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue