import type { IRun, WorkflowTestData } from 'n8n-workflow'; import { createDeferredPromise, Workflow } from 'n8n-workflow'; import { WorkflowExecute } from '@/WorkflowExecute'; import * as Helpers from './helpers'; import { initLogger } from './helpers/utils'; import { predefinedWorkflowExecuteTests } from './helpers/constants'; describe('WorkflowExecute', () => { beforeAll(() => { initLogger(); }); describe('run', () => { const tests: WorkflowTestData[] = predefinedWorkflowExecuteTests; const executionMode = 'manual'; const nodeTypes = Helpers.NodeTypes(); for (const testData of tests) { test(testData.description, async () => { const workflowInstance = new Workflow({ id: 'test', nodes: testData.input.workflowData.nodes, connections: testData.input.workflowData.connections, active: false, nodeTypes, }); const waitPromise = await createDeferredPromise(); const nodeExecutionOrder: string[] = []; const additionalData = Helpers.WorkflowExecuteAdditionalData( waitPromise, nodeExecutionOrder, ); const workflowExecute = new WorkflowExecute(additionalData, executionMode); const executionData = await workflowExecute.run(workflowInstance); const result = await waitPromise.promise(); // Check if the data from WorkflowExecute is identical to data received // by the webhooks expect(executionData).toEqual(result); // Check if the output data of the nodes is correct for (const nodeName of Object.keys(testData.output.nodeData)) { if (result.data.resultData.runData[nodeName] === undefined) { throw new Error(`Data for node "${nodeName}" is missing!`); } const resultData = result.data.resultData.runData[nodeName].map((nodeData) => { if (nodeData.data === undefined) { return null; } return nodeData.data.main[0]!.map((entry) => entry.json); }); expect(resultData).toEqual(testData.output.nodeData[nodeName]); } // Check if the nodes did execute in the correct order expect(nodeExecutionOrder).toEqual(testData.output.nodeExecutionOrder); // Check if other data has correct value expect(result.finished).toEqual(true); expect(result.data.executionData!.contextData).toEqual({}); expect(result.data.executionData!.nodeExecutionStack).toEqual([]); }); } }); //run tests on json files from specified directory, default 'workflows' //workflows must have pinned data that would be used to test output after execution describe('run test workflows', () => { const tests: WorkflowTestData[] = Helpers.workflowToTests(__dirname); const executionMode = 'manual'; const nodeTypes = Helpers.NodeTypes(Helpers.getNodeTypes(tests)); for (const testData of tests) { test(testData.description, async () => { const workflowInstance = new Workflow({ id: 'test', nodes: testData.input.workflowData.nodes, connections: testData.input.workflowData.connections, active: false, nodeTypes, }); const waitPromise = await createDeferredPromise(); const nodeExecutionOrder: string[] = []; const additionalData = Helpers.WorkflowExecuteAdditionalData( waitPromise, nodeExecutionOrder, ); const workflowExecute = new WorkflowExecute(additionalData, executionMode); const executionData = await workflowExecute.run(workflowInstance); const result = await waitPromise.promise(); // Check if the data from WorkflowExecute is identical to data received // by the webhooks expect(executionData).toEqual(result); // Check if the output data of the nodes is correct for (const nodeName of Object.keys(testData.output.nodeData)) { if (result.data.resultData.runData[nodeName] === undefined) { throw new Error(`Data for node "${nodeName}" is missing!`); } const resultData = result.data.resultData.runData[nodeName].map((nodeData) => { if (nodeData.data === undefined) { return null; } return nodeData.data.main[0]; }); expect(resultData).toEqual(testData.output.nodeData[nodeName]); } // Check if other data has correct value expect(result.finished).toEqual(true); // expect(result.data.executionData!.contextData).toEqual({}); //Fails when test workflow Includes splitInbatches expect(result.data.executionData!.nodeExecutionStack).toEqual([]); }); } }); });