diff --git a/packages/frontend/editor-ui/src/components/ParameterInput.test.ts b/packages/frontend/editor-ui/src/components/ParameterInput.test.ts index ed64b7b356..3ac3f9507b 100644 --- a/packages/frontend/editor-ui/src/components/ParameterInput.test.ts +++ b/packages/frontend/editor-ui/src/components/ParameterInput.test.ts @@ -4,7 +4,7 @@ import type { useNDVStore } from '@/stores/ndv.store'; import type { CompletionResult } from '@codemirror/autocomplete'; import { createTestingPinia } from '@pinia/testing'; import { faker } from '@faker-js/faker'; -import { waitFor } from '@testing-library/vue'; +import { waitFor, within } from '@testing-library/vue'; import userEvent from '@testing-library/user-event'; import type { useNodeTypesStore } from '@/stores/nodeTypes.store'; import { useSettingsStore } from '@/stores/settings.store'; @@ -556,4 +556,51 @@ describe('ParameterInput.vue', () => { eventBus.emit('optionSelected', 'removeExpression'); expect(emitted('update')).toContainEqual([expect.objectContaining({ value: '{{ }}' })]); }); + + test('should maintain focus after changing to expression', async () => { + const { rerender, getByRole, getByTestId } = renderComponent({ + props: { + path: 'name', + parameter: { + displayName: 'Name', + name: 'name', + type: 'string', + }, + modelValue: 'test', + }, + }); + const input = getByRole('textbox'); + expect(input).toBeInTheDocument(); + await userEvent.click(input); + await rerender({ modelValue: '={{ $json.foo }}' }); + + const expressionEditor = getByTestId('inline-expression-editor-input'); + expect(expressionEditor).toBeInTheDocument(); + const expressionEditorInput = within(expressionEditor).getByRole('textbox'); + await waitFor(() => expect(expressionEditorInput).toHaveFocus()); + }); + + describe('when not in focus', () => { + test('should not focus after changing to expression ', async () => { + const { rerender, getByRole, getByTestId } = renderComponent({ + props: { + path: 'name', + parameter: { + displayName: 'Name', + name: 'name', + type: 'string', + }, + modelValue: 'test', + }, + }); + const input = getByRole('textbox'); + expect(input).toBeInTheDocument(); + await rerender({ modelValue: '={{ $json.foo }}' }); + + const expressionEditor = getByTestId('inline-expression-editor-input'); + expect(expressionEditor).toBeInTheDocument(); + const expressionEditorInput = within(expressionEditor).getByRole('textbox'); + await waitFor(() => expect(expressionEditorInput).not.toHaveFocus()); + }); + }); }); diff --git a/packages/frontend/editor-ui/src/components/ParameterInput.vue b/packages/frontend/editor-ui/src/components/ParameterInput.vue index 8aef938222..d0e86375f0 100644 --- a/packages/frontend/editor-ui/src/components/ParameterInput.vue +++ b/packages/frontend/editor-ui/src/components/ParameterInput.vue @@ -1150,7 +1150,7 @@ watch(remoteParameterOptionsLoading, () => { // Focus input field when changing between fixed and expression watch(isModelValueExpression, async (isExpression, wasExpression) => { - if (!props.isReadOnly && isExpression !== wasExpression) { + if (!props.isReadOnly && isFocused.value && isExpression !== wasExpression) { await nextTick(); await setFocus(); }