From c7177719e5f60813f4d15f7f97f1b4f253e29b07 Mon Sep 17 00:00:00 2001 From: Mutasem Aldmour <4711238+mutdmour@users.noreply.github.com> Date: Wed, 10 May 2023 10:32:09 +0200 Subject: [PATCH] fix: Prevent overflow when rendering expression hints (#6214) * fix: Prevent whitespace overflow * fix: show overflow ellipsis * chore: add comment * chore: clean up other approach * test: update tests, fix test * test: uncomment test --- cypress/e2e/14-mapping.cy.ts | 16 ++++---- cypress/e2e/5-ndv.cy.ts | 38 +++++++++++++++++++ cypress/pages/ndv.ts | 15 +++++++- .../src/components/ParameterInputHint.vue | 18 ++++++--- 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/cypress/e2e/14-mapping.cy.ts b/cypress/e2e/14-mapping.cy.ts index afab75190e..2a42998ec7 100644 --- a/cypress/e2e/14-mapping.cy.ts +++ b/cypress/e2e/14-mapping.cy.ts @@ -156,7 +156,7 @@ describe('Data mapping', () => { ndv.getters .inlineExpressionEditorInput() .should('have.text', '{{ $json.input[0].count }} {{ $json.input }}'); - ndv.getters.parameterExpressionPreview('value').should('include.text', '0 [object Object]'); + ndv.actions.validateExpressionPreview('value', '0 [object Object]'); }); it('maps expressions from schema view', () => { @@ -172,7 +172,7 @@ describe('Data mapping', () => { ndv.actions.mapToParameter('value'); ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.input[0].count }}'); - ndv.getters.parameterExpressionPreview('value').should('include.text', '0'); + ndv.actions.validateExpressionPreview('value', '0'); ndv.getters.inputDataContainer().find('span').contains('input').realMouseDown(); @@ -180,7 +180,7 @@ describe('Data mapping', () => { ndv.getters .inlineExpressionEditorInput() .should('have.text', '{{ $json.input[0].count }} {{ $json.input }}'); - ndv.getters.parameterExpressionPreview('value').should('include.text', '0 [object Object]'); + ndv.actions.validateExpressionPreview('value', '0 [object Object]'); }); it('maps expressions from previous nodes', () => { @@ -205,17 +205,17 @@ describe('Data mapping', () => { 'have.text', `{{ $node['${SCHEDULE_TRIGGER_NODE_NAME}'].json.input[0].count }} {{ $node['${SCHEDULE_TRIGGER_NODE_NAME}'].json.input }}`, ); - ndv.getters.parameterExpressionPreview('value').should('have.text', ' '); + ndv.actions.validateExpressionPreview('value', ' '); ndv.actions.selectInputNode('Set'); ndv.actions.executePrevious(); ndv.getters.executingLoader().should('not.exist'); ndv.getters.inputDataContainer().should('exist'); - ndv.getters.parameterExpressionPreview('value').should('include.text', '0 [object Object]'); + ndv.actions.validateExpressionPreview('value', '0 [object Object]'); ndv.getters.inputTbodyCell(2, 0).realHover(); - ndv.getters.parameterExpressionPreview('value').should('include.text', '1 [object Object]'); + ndv.actions.validateExpressionPreview('value', '1 [object Object]'); }); it('maps keys to path', () => { @@ -282,7 +282,7 @@ describe('Data mapping', () => { ndv.actions.mapToParameter('value'); ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.input[0].count }}'); - ndv.getters.parameterExpressionPreview('value').should('include.text', '0'); + ndv.actions.validateExpressionPreview('value', '0'); ndv.getters.inputDataContainer().find('span').contains('input').realMouseDown(); @@ -290,7 +290,7 @@ describe('Data mapping', () => { ndv.getters .inlineExpressionEditorInput() .should('have.text', '{{ $json.input[0].count }} {{ $json.input }}'); - ndv.getters.parameterExpressionPreview('value').should('include.text', '0 [object Object]'); + ndv.actions.validateExpressionPreview('value', '0 [object Object]'); }); it('shows you can drop to inputs, including booleans', () => { diff --git a/cypress/e2e/5-ndv.cy.ts b/cypress/e2e/5-ndv.cy.ts index 749fb4434e..8c8809ad26 100644 --- a/cypress/e2e/5-ndv.cy.ts +++ b/cypress/e2e/5-ndv.cy.ts @@ -227,4 +227,42 @@ describe('NDV', () => { .find('input') .should('include.value', '2 of 2 (6 items)'); }); + + it('should display parameter hints correctly', () => { + workflowPage.actions.visit(); + + cy.createFixtureWorkflow('Test_workflow_3.json', `My test workflow`); + workflowPage.actions.openNode('Set1'); + + ndv.actions.typeIntoParameterInput('value', '='); // switch to expressions + + [ + { + input: 'hello', + }, + { + input: '', + output: '[empty]', + }, + { + input: ' test', + }, + { + input: ' ' + }, + { + input: '
' + }, + ].forEach(({ input, output }) => { + + + if (input) { + ndv.actions.typeIntoParameterInput('value', input); + } + ndv.getters.parameterInput('name').click(); // remove focus from input, hide expression preview + + ndv.actions.validateExpressionPreview('value', output || input); + ndv.getters.parameterInput('value').clear(); + }); + }); }); diff --git a/cypress/pages/ndv.ts b/cypress/pages/ndv.ts index f23f9a0548..f23eb97f4f 100644 --- a/cypress/pages/ndv.ts +++ b/cypress/pages/ndv.ts @@ -157,6 +157,19 @@ export class NDV extends BasePage { this.getters.resourceLocatorModeSelector(paramName).click(); this.getters.resourceLocatorModeSelector(paramName).find('li').last().click(); this.getters.resourceLocatorInput(paramName).type(value); - } + }, + validateExpressionPreview: (paramName: string, value: string) => { + this.getters.parameterExpressionPreview(paramName).find('span').should('include.html', asEncodedHTML(value)); + }, }; } + +function asEncodedHTML(str: string): string { + return String(str) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/ /g, ' '); +} + diff --git a/packages/editor-ui/src/components/ParameterInputHint.vue b/packages/editor-ui/src/components/ParameterInputHint.vue index d683e23537..99aba8dbc2 100644 --- a/packages/editor-ui/src/components/ParameterInputHint.vue +++ b/packages/editor-ui/src/components/ParameterInputHint.vue @@ -1,6 +1,6 @@