Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(editor): Prevent updating node parameter value if it hasn't changed #9535

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 0 additions & 71 deletions cypress/e2e/29-sql-editor.cy.ts

This file was deleted.

169 changes: 169 additions & 0 deletions cypress/e2e/41-editors.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import { WorkflowPage, NDV } from '../pages';

const workflowPage = new WorkflowPage();
const ndv = new NDV();

// Update is debounced in editors, so adding typing delay to catch up
const TYPING_DELAY = 100;

describe('Editors', () => {
beforeEach(() => {
workflowPage.actions.visit();
});

describe('SQL Editor', () => {

it('should preserve changes when opening-closing Postgres node', () => {
workflowPage.actions.addInitialNodeToCanvas('Postgres', {
action: 'Execute a SQL query',
keepNdvOpen: true,
});
ndv.getters
.sqlEditorContainer()
.click()
.find('.cm-content')
.type('SELECT * FROM `testTable`', { delay: TYPING_DELAY })
.type('{esc}');
ndv.actions.close();
workflowPage.actions.openNode('Postgres');
ndv.getters.sqlEditorContainer().find('.cm-content').type('{end} LIMIT 10', { delay: TYPING_DELAY }).type('{esc}');
ndv.actions.close();
workflowPage.actions.openNode('Postgres');
ndv.getters.sqlEditorContainer().should('contain', 'SELECT * FROM `testTable` LIMIT 10');
});

it('should update expression output dropdown as the query is edited', () => {
workflowPage.actions.addInitialNodeToCanvas('MySQL', {
action: 'Execute a SQL query',
});
ndv.actions.close();

workflowPage.actions.openNode('When clicking "Test workflow"');
ndv.actions.setPinnedData([{ table: 'test_table' }]);
ndv.actions.close();

workflowPage.actions.openNode('MySQL');
ndv.getters
.sqlEditorContainer()
.find('.cm-content')
.type('SELECT * FROM {{ $json.table }}', { parseSpecialCharSequences: false });
workflowPage.getters
.inlineExpressionEditorOutput()
.should('have.text', 'SELECT * FROM test_table');
});

it('should not push NDV header out with a lot of code in Postgres editor', () => {
workflowPage.actions.addInitialNodeToCanvas('Postgres', {
action: 'Execute a SQL query',
keepNdvOpen: true,
});
cy.fixture('Dummy_javascript.txt').then((code) => {
ndv.getters.sqlEditorContainer().find('.cm-content').paste(code);
});
ndv.getters.nodeExecuteButton().should('be.visible');
});

it('should not push NDV header out with a lot of code in MySQL editor', () => {
workflowPage.actions.addInitialNodeToCanvas('MySQL', {
action: 'Execute a SQL query',
keepNdvOpen: true,
});
cy.fixture('Dummy_javascript.txt').then((code) => {
ndv.getters.sqlEditorContainer().find('.cm-content').paste(code);
});
ndv.getters.nodeExecuteButton().should('be.visible');
});

it('should not trigger dirty flag if nothing is changed', () => {
workflowPage.actions.addInitialNodeToCanvas('Postgres', {
action: 'Execute a SQL query',
keepNdvOpen: true,
});
ndv.actions.close();
workflowPage.actions.saveWorkflowOnButtonClick();
workflowPage.getters.isWorkflowSaved();
workflowPage.actions.openNode('Postgres');
ndv.actions.close();
// Workflow should still be saved
workflowPage.getters.isWorkflowSaved();
});

it('should trigger dirty flag if query is updated', () => {
workflowPage.actions.addInitialNodeToCanvas('Postgres', {
action: 'Execute a SQL query',
keepNdvOpen: true,
});
ndv.actions.close();
workflowPage.actions.saveWorkflowOnButtonClick();
workflowPage.getters.isWorkflowSaved();
workflowPage.actions.openNode('Postgres');
ndv.getters
.sqlEditorContainer()
.click()
.find('.cm-content')
.type('SELECT * FROM `testTable`', { delay: TYPING_DELAY })
.type('{esc}');
ndv.actions.close();
workflowPage.getters.isWorkflowSaved().should('not.be.true');
});
});

describe('HTML Editor', () => {
// Closing tags will be added by the editor
const TEST_ELEMENT_H1 = '<h1>Test';
const TEST_ELEMENT_P = '<p>Test';

it('should preserve changes when opening-closing HTML node', () => {
workflowPage.actions.addInitialNodeToCanvas('HTML', {
action: 'Generate HTML template',
keepNdvOpen: true,
});
ndv.getters
.htmlEditorContainer()
.click()
.find('.cm-content')
.type(`{selectall}${TEST_ELEMENT_H1}`, { delay: TYPING_DELAY, force: true })
.type('{esc}');
ndv.actions.close();
workflowPage.actions.openNode('HTML');
ndv.getters.htmlEditorContainer().find('.cm-content').type(`{end}${TEST_ELEMENT_P}`, { delay: TYPING_DELAY, force: true }).type('{esc}');
ndv.actions.close();
workflowPage.actions.openNode('HTML');
ndv.getters.htmlEditorContainer().should('contain', TEST_ELEMENT_H1);
ndv.getters.htmlEditorContainer().should('contain', TEST_ELEMENT_P);
});

it('should not trigger dirty flag if nothing is changed', () => {
workflowPage.actions.addInitialNodeToCanvas('HTML', {
action: 'Generate HTML template',
keepNdvOpen: true,
});
ndv.actions.close();
workflowPage.actions.saveWorkflowOnButtonClick();
workflowPage.getters.isWorkflowSaved();
workflowPage.actions.openNode('HTML');
ndv.actions.close();
// Workflow should still be saved
workflowPage.getters.isWorkflowSaved();
});

it('should trigger dirty flag if query is updated', () => {
workflowPage.actions.addInitialNodeToCanvas('HTML', {
action: 'Generate HTML template',
keepNdvOpen: true,
});
ndv.actions.close();
workflowPage.actions.saveWorkflowOnButtonClick();
workflowPage.getters.isWorkflowSaved();
workflowPage.actions.openNode('HTML');
ndv.getters
.htmlEditorContainer()
.click()
.find('.cm-content')
.type(`{selectall}${TEST_ELEMENT_H1}`, { delay: TYPING_DELAY, force: true })
.type('{esc}');
ndv.actions.close();
workflowPage.getters.isWorkflowSaved().should('not.be.true');
});
});
});
1 change: 1 addition & 0 deletions cypress/pages/ndv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export class NDV extends BasePage {
cy.getByTestId('columns-parameter-input-options-container'),
resourceMapperRemoveAllFieldsOption: () => cy.getByTestId('action-removeAllFields'),
sqlEditorContainer: () => cy.getByTestId('sql-editor-container'),
htmlEditorContainer: () => cy.getByTestId('html-editor-container'),
filterComponent: (paramName: string) => cy.getByTestId(`filter-${paramName}`),
filterCombinator: (paramName: string, index = 0) =>
this.getters.filterComponent(paramName).getByTestId('filter-combinator-select').eq(index),
Expand Down
3 changes: 1 addition & 2 deletions packages/editor-ui/src/components/HtmlEditor/HtmlEditor.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div :class="$style.editor">
<div ref="htmlEditor"></div>
<div ref="htmlEditor" data-test-id="html-editor-container"></div>
<slot name="suffix" />
</div>
</template>
Expand Down Expand Up @@ -244,7 +244,6 @@ onMounted(() => {

onBeforeUnmount(() => {
htmlEditorEventBus.off('format-html', formatHtml);
emit('update:model-value', readEditorValue());
});
</script>

Expand Down
7 changes: 7 additions & 0 deletions packages/editor-ui/src/components/ParameterInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,13 @@ function valueChanged(value: NodeParameterValueType | {} | Date) {
if (remoteParameterOptionsLoading.value) {
return;
}
// Only update the value if it has changed
const oldValue = node.value?.parameters
? nodeHelpers.getParameterValue(node.value?.parameters, props.parameter.name, '')
: undefined;
if (oldValue !== undefined && oldValue === value) {
return;
}

if (props.parameter.name === 'nodeCredentialType') {
activeCredentialType.value = value as string;
Expand Down
1 change: 0 additions & 1 deletion packages/editor-ui/src/components/SqlEditor/SqlEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ onMounted(() => {

onBeforeUnmount(() => {
codeNodeEditorEventBus.off('error-line-number', highlightLine);
emit('update:model-value', readEditorValue());
});

function line(lineNumber: number): Line | null {
Expand Down
Loading