mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 20:24:05 -08:00
fix: Prevent chat modal opening on 'Test workflow' click (#9009)
Signed-off-by: Oleg Ivaniv <me@olegivaniv.com> Co-authored-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
parent
bead7eb840
commit
3fd97e4c72
|
@ -48,6 +48,12 @@ export function getNodeByName(name: string) {
|
||||||
return cy.getByTestId('canvas-node').filter(`[data-name="${name}"]`).eq(0);
|
return cy.getByTestId('canvas-node').filter(`[data-name="${name}"]`).eq(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function disableNode(name: string) {
|
||||||
|
const target = getNodeByName(name);
|
||||||
|
target.rightclick(name ? 'center' : 'topLeft', { force: true });
|
||||||
|
cy.getByTestId(`context-menu-item-toggle_activation`).click();
|
||||||
|
}
|
||||||
|
|
||||||
export function getConnectionBySourceAndTarget(source: string, target: string) {
|
export function getConnectionBySourceAndTarget(source: string, target: string) {
|
||||||
return cy
|
return cy
|
||||||
.get('.jtk-connector')
|
.get('.jtk-connector')
|
||||||
|
@ -110,14 +116,20 @@ export function addSupplementalNodeToParent(
|
||||||
) {
|
) {
|
||||||
getAddInputEndpointByType(parentNodeName, endpointType).click({ force: true });
|
getAddInputEndpointByType(parentNodeName, endpointType).click({ force: true });
|
||||||
if (exactMatch) {
|
if (exactMatch) {
|
||||||
getNodeCreatorItems().contains(new RegExp("^" + nodeName + "$", "g")).click();
|
getNodeCreatorItems()
|
||||||
|
.contains(new RegExp('^' + nodeName + '$', 'g'))
|
||||||
|
.click();
|
||||||
} else {
|
} else {
|
||||||
getNodeCreatorItems().contains(nodeName).click();
|
getNodeCreatorItems().contains(nodeName).click();
|
||||||
}
|
}
|
||||||
getConnectionBySourceAndTarget(parentNodeName, nodeName).should('exist');
|
getConnectionBySourceAndTarget(parentNodeName, nodeName).should('exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addLanguageModelNodeToParent(nodeName: string, parentNodeName: string, exactMatch = false) {
|
export function addLanguageModelNodeToParent(
|
||||||
|
nodeName: string,
|
||||||
|
parentNodeName: string,
|
||||||
|
exactMatch = false,
|
||||||
|
) {
|
||||||
addSupplementalNodeToParent(nodeName, 'ai_languageModel', parentNodeName, exactMatch);
|
addSupplementalNodeToParent(nodeName, 'ai_languageModel', parentNodeName, exactMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
AI_TOOL_CODE_NODE_NAME,
|
AI_TOOL_CODE_NODE_NAME,
|
||||||
AI_TOOL_WIKIPEDIA_NODE_NAME,
|
AI_TOOL_WIKIPEDIA_NODE_NAME,
|
||||||
BASIC_LLM_CHAIN_NODE_NAME,
|
BASIC_LLM_CHAIN_NODE_NAME,
|
||||||
|
EDIT_FIELDS_SET_NODE_NAME,
|
||||||
} from './../constants';
|
} from './../constants';
|
||||||
import { createMockNodeExecutionData, runMockWorkflowExcution } from '../utils';
|
import { createMockNodeExecutionData, runMockWorkflowExcution } from '../utils';
|
||||||
import {
|
import {
|
||||||
|
@ -17,7 +18,10 @@ import {
|
||||||
addNodeToCanvas,
|
addNodeToCanvas,
|
||||||
addOutputParserNodeToParent,
|
addOutputParserNodeToParent,
|
||||||
addToolNodeToParent,
|
addToolNodeToParent,
|
||||||
|
clickExecuteWorkflowButton,
|
||||||
clickManualChatButton,
|
clickManualChatButton,
|
||||||
|
disableNode,
|
||||||
|
getExecuteWorkflowButton,
|
||||||
navigateToNewWorkflowPage,
|
navigateToNewWorkflowPage,
|
||||||
openNode,
|
openNode,
|
||||||
} from '../composables/workflow';
|
} from '../composables/workflow';
|
||||||
|
@ -32,6 +36,7 @@ import {
|
||||||
closeManualChatModal,
|
closeManualChatModal,
|
||||||
getManualChatDialog,
|
getManualChatDialog,
|
||||||
getManualChatMessages,
|
getManualChatMessages,
|
||||||
|
getManualChatModal,
|
||||||
getManualChatModalLogs,
|
getManualChatModalLogs,
|
||||||
getManualChatModalLogsEntries,
|
getManualChatModalLogsEntries,
|
||||||
getManualChatModalLogsTree,
|
getManualChatModalLogsTree,
|
||||||
|
@ -43,13 +48,58 @@ describe('Langchain Integration', () => {
|
||||||
navigateToNewWorkflowPage();
|
navigateToNewWorkflowPage();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not open chat modal', () => {
|
||||||
|
addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
|
||||||
|
addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, true);
|
||||||
|
|
||||||
|
clickGetBackToCanvas();
|
||||||
|
|
||||||
|
addNodeToCanvas(AGENT_NODE_NAME, true, true);
|
||||||
|
clickGetBackToCanvas();
|
||||||
|
|
||||||
|
addLanguageModelNodeToParent(
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
clickGetBackToCanvas();
|
||||||
|
|
||||||
|
clickExecuteWorkflowButton();
|
||||||
|
getManualChatModal().should('not.exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should disable test workflow button', () => {
|
||||||
|
addNodeToCanvas('Schedule Trigger', true);
|
||||||
|
addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, true);
|
||||||
|
|
||||||
|
clickGetBackToCanvas();
|
||||||
|
|
||||||
|
addNodeToCanvas(AGENT_NODE_NAME, true, true);
|
||||||
|
clickGetBackToCanvas();
|
||||||
|
|
||||||
|
addLanguageModelNodeToParent(
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
clickGetBackToCanvas();
|
||||||
|
|
||||||
|
disableNode('Schedule Trigger');
|
||||||
|
|
||||||
|
getExecuteWorkflowButton().should('be.disabled');
|
||||||
|
});
|
||||||
|
|
||||||
it('should add nodes to all Agent node input types', () => {
|
it('should add nodes to all Agent node input types', () => {
|
||||||
addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
|
addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
|
||||||
addNodeToCanvas(AGENT_NODE_NAME, true, true);
|
addNodeToCanvas(AGENT_NODE_NAME, true, true);
|
||||||
toggleParameterCheckboxInputByName('hasOutputParser');
|
toggleParameterCheckboxInputByName('hasOutputParser');
|
||||||
clickGetBackToCanvas();
|
clickGetBackToCanvas();
|
||||||
|
|
||||||
addLanguageModelNodeToParent(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, AGENT_NODE_NAME, true);
|
addLanguageModelNodeToParent(
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
true,
|
||||||
|
);
|
||||||
clickGetBackToCanvas();
|
clickGetBackToCanvas();
|
||||||
|
|
||||||
addMemoryNodeToParent(AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME, AGENT_NODE_NAME);
|
addMemoryNodeToParent(AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME, AGENT_NODE_NAME);
|
||||||
|
@ -85,7 +135,7 @@ describe('Langchain Integration', () => {
|
||||||
addLanguageModelNodeToParent(
|
addLanguageModelNodeToParent(
|
||||||
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
BASIC_LLM_CHAIN_NODE_NAME,
|
BASIC_LLM_CHAIN_NODE_NAME,
|
||||||
true
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
clickCreateNewCredential();
|
clickCreateNewCredential();
|
||||||
|
@ -98,7 +148,7 @@ describe('Langchain Integration', () => {
|
||||||
const inputMessage = 'Hello!';
|
const inputMessage = 'Hello!';
|
||||||
const outputMessage = 'Hi there! How can I assist you today?';
|
const outputMessage = 'Hi there! How can I assist you today?';
|
||||||
|
|
||||||
clickExecuteNode()
|
clickExecuteNode();
|
||||||
runMockWorkflowExcution({
|
runMockWorkflowExcution({
|
||||||
trigger: () => sendManualChatMessage(inputMessage),
|
trigger: () => sendManualChatMessage(inputMessage),
|
||||||
runData: [
|
runData: [
|
||||||
|
@ -121,7 +171,11 @@ describe('Langchain Integration', () => {
|
||||||
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true);
|
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true);
|
||||||
addNodeToCanvas(AGENT_NODE_NAME, true);
|
addNodeToCanvas(AGENT_NODE_NAME, true);
|
||||||
|
|
||||||
addLanguageModelNodeToParent(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, AGENT_NODE_NAME, true);
|
addLanguageModelNodeToParent(
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
clickCreateNewCredential();
|
clickCreateNewCredential();
|
||||||
setCredentialValues({
|
setCredentialValues({
|
||||||
|
@ -134,7 +188,7 @@ describe('Langchain Integration', () => {
|
||||||
const inputMessage = 'Hello!';
|
const inputMessage = 'Hello!';
|
||||||
const outputMessage = 'Hi there! How can I assist you today?';
|
const outputMessage = 'Hi there! How can I assist you today?';
|
||||||
|
|
||||||
clickExecuteNode()
|
clickExecuteNode();
|
||||||
runMockWorkflowExcution({
|
runMockWorkflowExcution({
|
||||||
trigger: () => sendManualChatMessage(inputMessage),
|
trigger: () => sendManualChatMessage(inputMessage),
|
||||||
runData: [
|
runData: [
|
||||||
|
@ -157,7 +211,11 @@ describe('Langchain Integration', () => {
|
||||||
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true);
|
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true);
|
||||||
addNodeToCanvas(AGENT_NODE_NAME, true);
|
addNodeToCanvas(AGENT_NODE_NAME, true);
|
||||||
|
|
||||||
addLanguageModelNodeToParent(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, AGENT_NODE_NAME, true);
|
addLanguageModelNodeToParent(
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
clickCreateNewCredential();
|
clickCreateNewCredential();
|
||||||
setCredentialValues({
|
setCredentialValues({
|
||||||
|
|
|
@ -247,6 +247,33 @@ export function useRunWorkflow(options: { router: ReturnType<typeof useRouter> }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if no destination node is specified
|
||||||
|
//and execution is not triggered from chat
|
||||||
|
//and there are other triggers in the workflow
|
||||||
|
//disable chat trigger node to avoid modal opening and webhook creation
|
||||||
|
if (
|
||||||
|
!options.destinationNode &&
|
||||||
|
options.source !== 'RunData.ManualChatMessage' &&
|
||||||
|
workflowData.nodes.some((node) => node.type === CHAT_TRIGGER_NODE_TYPE)
|
||||||
|
) {
|
||||||
|
const otherTriggers = workflowData.nodes.filter(
|
||||||
|
(node) =>
|
||||||
|
node.type !== CHAT_TRIGGER_NODE_TYPE &&
|
||||||
|
node.type.toLowerCase().includes('trigger') &&
|
||||||
|
!node.disabled,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (otherTriggers.length) {
|
||||||
|
const chatTriggerNode = workflowData.nodes.find(
|
||||||
|
(node) => node.type === CHAT_TRIGGER_NODE_TYPE,
|
||||||
|
);
|
||||||
|
if (chatTriggerNode) {
|
||||||
|
chatTriggerNode.disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const startNodes: StartNodeData[] = startNodeNames.map((name) => {
|
const startNodes: StartNodeData[] = startNodeNames.map((name) => {
|
||||||
// Find for each start node the source data
|
// Find for each start node the source data
|
||||||
let sourceData = get(runData, [name, 0, 'source', 0], null);
|
let sourceData = get(runData, [name, 0, 'source', 0], null);
|
||||||
|
|
|
@ -728,6 +728,12 @@ export default defineComponent({
|
||||||
return this.containsChatNodes && this.triggerNodes.length === 1;
|
return this.containsChatNodes && this.triggerNodes.length === 1;
|
||||||
},
|
},
|
||||||
isExecutionDisabled(): boolean {
|
isExecutionDisabled(): boolean {
|
||||||
|
if (
|
||||||
|
this.containsChatNodes &&
|
||||||
|
this.triggerNodes.every((node) => node.disabled || node.type === CHAT_TRIGGER_NODE_TYPE)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return !this.containsTrigger || this.allTriggersDisabled;
|
return !this.containsTrigger || this.allTriggersDisabled;
|
||||||
},
|
},
|
||||||
getNodeViewOffsetPosition(): XYPosition {
|
getNodeViewOffsetPosition(): XYPosition {
|
||||||
|
|
Loading…
Reference in a new issue