diff --git a/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionEditorModalInput.vue b/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionEditorModalInput.vue
index bccb83c72b632..52bac85329ceb 100644
--- a/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionEditorModalInput.vue
+++ b/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionEditorModalInput.vue
@@ -1,5 +1,5 @@
-
+
-
+
+
diff --git a/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionEditorModalOutput.vue b/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionEditorModalOutput.vue
index de1d60abecf43..0f79ef4ee6faf 100644
--- a/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionEditorModalOutput.vue
+++ b/packages/editor-ui/src/components/ExpressionEditorModal/ExpressionEditorModalOutput.vue
@@ -75,6 +75,7 @@ export default defineComponent({
outputTheme(),
EditorState.readOnly.of(true),
EditorView.lineWrapping,
+ EditorView.editable.of(false),
EditorView.domEventHandlers({ scroll: forceParse }),
];
diff --git a/packages/editor-ui/src/components/ExpressionParameterInput.vue b/packages/editor-ui/src/components/ExpressionParameterInput.vue
index 091c04e26621a..be5a0f7ef81be 100644
--- a/packages/editor-ui/src/components/ExpressionParameterInput.vue
+++ b/packages/editor-ui/src/components/ExpressionParameterInput.vue
@@ -20,8 +20,11 @@
@blur="onBlur"
@change="onChange"
/>
-
-
+
-
+
+
+
diff --git a/packages/editor-ui/src/components/__tests__/ExpressionEditorModalInput.test.ts b/packages/editor-ui/src/components/__tests__/ExpressionEditorModalInput.test.ts
new file mode 100644
index 0000000000000..3793d3d760483
--- /dev/null
+++ b/packages/editor-ui/src/components/__tests__/ExpressionEditorModalInput.test.ts
@@ -0,0 +1,39 @@
+import userEvent from '@testing-library/user-event';
+import { createComponentRenderer } from '@/__tests__/render';
+import ExpressionEditorModalInput from '@/components/ExpressionEditorModal/ExpressionEditorModalInput.vue';
+
+const renderComponent = createComponentRenderer(ExpressionEditorModalInput);
+
+const originalRangeGetBoundingClientRect = Range.prototype.getBoundingClientRect;
+const originalRangeGetClientRects = Range.prototype.getClientRects;
+
+describe('ExpressionParameterInput', () => {
+ beforeAll(() => {
+ Range.prototype.getBoundingClientRect = vi.fn();
+ Range.prototype.getClientRects = () => ({
+ item: vi.fn(),
+ length: 0,
+ [Symbol.iterator]: vi.fn(),
+ });
+ });
+
+ afterAll(() => {
+ Range.prototype.getBoundingClientRect = originalRangeGetBoundingClientRect;
+ Range.prototype.getClientRects = originalRangeGetClientRects;
+ });
+ test.each([
+ ['not be editable', 'readonly', true, ''],
+ ['be editable', 'not readonly', false, 'test'],
+ ])('should %s when %s', async (_, __, isReadOnly, expected) => {
+ const { getByRole } = renderComponent({
+ props: {
+ modelValue: '',
+ path: '',
+ isReadOnly,
+ },
+ });
+
+ await userEvent.type(getByRole('textbox'), 'test');
+ expect(getByRole('textbox')).toHaveTextContent(expected);
+ });
+});
diff --git a/packages/editor-ui/src/components/__tests__/ExpressionParameterInput.test.ts b/packages/editor-ui/src/components/__tests__/ExpressionParameterInput.test.ts
new file mode 100644
index 0000000000000..43e5d73eb8b9b
--- /dev/null
+++ b/packages/editor-ui/src/components/__tests__/ExpressionParameterInput.test.ts
@@ -0,0 +1,36 @@
+import { createPinia, setActivePinia } from 'pinia';
+import userEvent from '@testing-library/user-event';
+import { createComponentRenderer } from '@/__tests__/render';
+import { useWorkflowsStore } from '@/stores/workflows.store';
+import { useNDVStore } from '@/stores/ndv.store';
+import ExpressionParameterInput from '@/components/ExpressionParameterInput.vue';
+
+const renderComponent = createComponentRenderer(ExpressionParameterInput);
+
+let pinia: ReturnType;
+let workflowsStore: ReturnType;
+let ndvStore: ReturnType;
+
+describe('ExpressionParameterInput', () => {
+ beforeEach(() => {
+ pinia = createPinia();
+ setActivePinia(pinia);
+ workflowsStore = useWorkflowsStore();
+ ndvStore = useNDVStore();
+ });
+
+ test.each([
+ ['not readonly', false, expect.anything()],
+ ['readonly', true, expect.anything()],
+ ])('should emit open expression editor modal when %s', async (_, isReadOnly, expected) => {
+ const { getByTestId, emitted } = renderComponent({
+ props: {
+ modelValue: '',
+ isReadOnly,
+ },
+ });
+
+ await userEvent.click(getByTestId('expander'));
+ expect(emitted().modalOpenerClick).toEqual(expected);
+ });
+});