import { nanoid } from 'nanoid'; import { test, expect } from '../../../fixtures/base'; test.use({ capability: 'kafka' }); test.describe('Kafka Nodes', { annotation: [ { type: 'owner', description: 'NODES' }, ], }, () => { test('Kafka node publishes messages to topic @capability:kafka', async ({ api, n8n, services, }) => { const kafka = services.kafka; const topic = `producer-test-${nanoid()}`; const testPayload = { greeting: 'Hello from n8n Kafka node' }; await kafka.createTopic(topic, 1); const kafkaCredential = await api.credentials.createCredential({ name: 'Kafka (Test)', type: 'kafka', data: { brokers: 'kafka:9092', clientId: 'n8n-test-producer', ssl: false, authentication: false, }, }); const workflowDefinition = { name: 'Kafka Producer Test', nodes: [ { id: '1', name: 'Manual Trigger', type: 'n8n-nodes-base.manualTrigger', typeVersion: 1, position: [0, 0] as [number, number], }, { id: '2', name: 'Set', type: 'n8n-nodes-base.set', typeVersion: 3, position: [200, 0] as [number, number], parameters: { mode: 'raw', jsonOutput: JSON.stringify(testPayload), }, }, { id: '3', name: 'Kafka', type: 'n8n-nodes-base.kafka', typeVersion: 1, position: [400, 0] as [number, number], parameters: { topic, sendInputData: true, useKey: true, key: 'test-key', options: {}, }, credentials: { kafka: { id: kafkaCredential.id, name: kafkaCredential.name, }, }, }, ], connections: { 'Manual Trigger': { main: [[{ node: 'Set', type: 'main', index: 0 }]], }, Set: { main: [[{ node: 'Kafka', type: 'main', index: 0 }]], }, }, active: false, }; const { workflowId } = await api.workflows.createWorkflowFromDefinition( // eslint-disable-next-line @typescript-eslint/no-explicit-any workflowDefinition as any, { makeUnique: true }, ); await n8n.page.goto(`/workflow/${workflowId}`); await n8n.workflowComposer.executeWorkflowAndWaitForNotification( 'Workflow executed successfully', ); const messages = await kafka.consume(topic, { maxMessages: 1, timeoutMs: 10000 }); expect(messages).toHaveLength(1); expect(messages[0].key).toBe('test-key'); expect(JSON.parse(messages[0].value)).toMatchObject(testPayload); }); test('Kafka Trigger node processes messages @capability:kafka', async ({ api, services }) => { const kafka = services.kafka; const topic = `trigger-test-${nanoid()}`; const groupId = `n8n-test-group-${nanoid()}`; await kafka.createTopic(topic, 1); const kafkaCredential = await api.credentials.createCredential({ name: 'Kafka (Test)', type: 'kafka', data: { brokers: 'kafka:9092', clientId: 'n8n-test', ssl: false, authentication: false, }, }); const workflowDefinition = { name: 'Kafka Trigger Test', nodes: [ { id: '1', name: 'Kafka Trigger', type: 'n8n-nodes-base.kafkaTrigger', typeVersion: 1.1, position: [0, 0] as [number, number], parameters: { topic, groupId, options: { fromBeginning: true, jsonParseMessage: true, parallelProcessing: false, }, }, credentials: { kafka: { id: kafkaCredential.id, name: kafkaCredential.name, }, }, }, { id: '2', name: 'No Operation', type: 'n8n-nodes-base.noOp', typeVersion: 1, position: [200, 0] as [number, number], }, ], connections: { 'Kafka Trigger': { main: [[{ node: 'No Operation', type: 'main', index: 0 }]], }, }, active: false, }; const { workflowId, createdWorkflow } = await api.workflows.createWorkflowFromDefinition( // eslint-disable-next-line @typescript-eslint/no-explicit-any workflowDefinition as any, { makeUnique: true }, ); await api.workflows.activate(workflowId, createdWorkflow.versionId!); await kafka.waitForConsumerGroup(groupId); const testPayload = { test: 'message' }; await kafka.publish(topic, testPayload); const execution = await api.workflows.waitForExecution(workflowId, 10000, 'trigger'); expect(execution.status).toBe('success'); }); });