import { AGENT_NODE_NAME, AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, BASIC_LLM_CHAIN_NODE_NAME, CHAT_TRIGGER_NODE_DISPLAY_NAME, MANUAL_CHAT_TRIGGER_NODE_NAME, } from '../../../config/constants'; import { test, expect } from '../../../fixtures/base'; import type { n8nPage } from '../../../pages/n8nPage'; // Helper functions for common operations async function addOpenAILanguageModelWithCredentials( n8n: n8nPage, parentNode: string, options: { exactMatch?: boolean; closeNDV?: boolean } = { exactMatch: true, closeNDV: false }, ) { await n8n.canvas.addSupplementalNodeToParent( AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, 'ai_languageModel', parentNode, options, ); await n8n.credentialsComposer.createFromNdv({ apiKey: 'abcd', }); await n8n.ndv.clickBackToCanvasButton(); } async function waitForWorkflowSuccess(n8n: n8nPage, timeout = 3000) { await n8n.notifications.waitForNotificationAndClose('Workflow executed successfully', { timeout, }); } async function executeChatAndWaitForResponse(n8n: n8nPage, message: string) { await n8n.canvas.logsPanel.sendManualChatMessage(message); await waitForWorkflowSuccess(n8n); } test.use({ capability: 'proxy' }); test.describe('Langchain Integration @capability:proxy', { annotation: [ { type: 'owner', description: 'AI' }, ], }, () => { test.beforeEach(async ({ n8n, services }) => { await services.proxy.clearAllExpectations(); await services.proxy.loadExpectations('langchain'); await n8n.canvas.openNewWorkflow(); }); test.describe('Auto-add Behavior', () => { test('should auto-add chat trigger and basic LLM chain when adding LLM node', async ({ n8n, }) => { await n8n.canvas.addNode(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, { closeNDV: true }); await expect( n8n.canvas.connectionBetweenNodes( CHAT_TRIGGER_NODE_DISPLAY_NAME, BASIC_LLM_CHAIN_NODE_NAME, ), ).toBeAttached(); await expect( n8n.canvas.connectionBetweenNodes( AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, BASIC_LLM_CHAIN_NODE_NAME, ), ).toBeAttached(); await expect(n8n.canvas.getCanvasNodes()).toHaveCount(3); }); test('should not auto-add nodes if AI nodes are already present', async ({ n8n }) => { await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: true }); await n8n.canvas.addNode(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, { closeNDV: true }); await expect( n8n.canvas.connectionBetweenNodes(CHAT_TRIGGER_NODE_DISPLAY_NAME, AGENT_NODE_NAME), ).toBeAttached(); await expect(n8n.canvas.getCanvasNodes()).toHaveCount(3); }); test('should not auto-add nodes if ChatTrigger is already present', async ({ n8n }) => { await n8n.canvas.addNode(MANUAL_CHAT_TRIGGER_NODE_NAME, { closeNDV: true, trigger: 'On new Chat event', }); await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: true }); await n8n.canvas.addNode(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, { closeNDV: true }); await expect( n8n.canvas.connectionBetweenNodes(CHAT_TRIGGER_NODE_DISPLAY_NAME, AGENT_NODE_NAME), ).toBeAttached(); await expect(n8n.canvas.getCanvasNodes()).toHaveCount(3); }); }); test.describe('Chat Execution and Interaction', () => { test('should be able to open and execute Basic LLM Chain node', async ({ n8n }) => { await n8n.canvas.addNode(BASIC_LLM_CHAIN_NODE_NAME, { closeNDV: true }); await addOpenAILanguageModelWithCredentials(n8n, BASIC_LLM_CHAIN_NODE_NAME); await n8n.canvas.openNode(BASIC_LLM_CHAIN_NODE_NAME); const inputMessage = 'Hello!'; await n8n.ndv.execute(); await executeChatAndWaitForResponse(n8n, inputMessage); // Verify chat message appears await expect(n8n.canvas.getManualChatLatestBotMessage()).toBeVisible(); }); }); });