From fc6d4138d58282f676b32f1a6011b1b6d0184bf2 Mon Sep 17 00:00:00 2001 From: Elias Meire Date: Fri, 16 Aug 2024 15:30:20 +0200 Subject: [PATCH] fix(editor): Fix flaky mapping tests (#10453) --- cypress/e2e/14-mapping.cy.ts | 22 ++++++++++++++----- cypress/e2e/33-settings-personal.cy.ts | 4 ++-- cypress/pages/ndv.ts | 2 +- cypress/support/e2e.ts | 2 ++ .../__tests__/no-url.validator.test.ts | 2 +- .../cli/src/validators/no-url.validator.ts | 2 +- 6 files changed, 23 insertions(+), 11 deletions(-) diff --git a/cypress/e2e/14-mapping.cy.ts b/cypress/e2e/14-mapping.cy.ts index 2e405e69e88c4..43103415e3c04 100644 --- a/cypress/e2e/14-mapping.cy.ts +++ b/cypress/e2e/14-mapping.cy.ts @@ -40,6 +40,8 @@ describe('Data mapping', () => { ndv.actions.mapDataFromHeader(1, 'value'); ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.timestamp }}'); + ndv.getters.inlineExpressionEditorInput().type('{esc}'); + ndv.getters.parameterExpressionPreview('value').should('include.text', '2024'); ndv.actions.mapDataFromHeader(2, 'value'); ndv.getters @@ -133,6 +135,7 @@ describe('Data mapping', () => { ndv.actions.mapToParameter('value'); ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.input[0].count }}'); + ndv.getters.inlineExpressionEditorInput().type('{esc}'); ndv.getters.parameterExpressionPreview('value').should('include.text', '0'); ndv.getters @@ -146,6 +149,7 @@ describe('Data mapping', () => { ndv.getters .inlineExpressionEditorInput() .should('have.text', '{{ $json.input }}{{ $json.input[0].count }}'); + ndv.getters.inlineExpressionEditorInput().type('{esc}'); ndv.actions.validateExpressionPreview('value', '[object Object]0'); }); @@ -163,6 +167,7 @@ describe('Data mapping', () => { ndv.actions.mapToParameter('value'); ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.input[0].count }}'); + ndv.getters.inlineExpressionEditorInput().type('{esc}'); ndv.actions.validateExpressionPreview('value', '0'); ndv.getters.inputDataContainer().find('span').contains('input').realMouseDown(); @@ -192,6 +197,7 @@ describe('Data mapping', () => { ndv.getters .inlineExpressionEditorInput() .should('have.text', `{{ $('${SCHEDULE_TRIGGER_NODE_NAME}').item.json.input[0].count }}`); + ndv.getters.inlineExpressionEditorInput().type('{esc}'); ndv.actions.switchInputMode('Table'); ndv.actions.selectInputNode(SCHEDULE_TRIGGER_NODE_NAME); @@ -271,12 +277,12 @@ describe('Data mapping', () => { ndv.actions.typeIntoParameterInput('value', 'fun'); ndv.actions.clearParameterInput('value'); // keep focus on param - cy.wait(300); ndv.getters.inputDataContainer().should('exist').find('span').contains('count').realMouseDown(); ndv.actions.mapToParameter('value'); ndv.getters.inlineExpressionEditorInput().should('have.text', '{{ $json.input[0].count }}'); + ndv.getters.inlineExpressionEditorInput().type('{esc}'); ndv.actions.validateExpressionPreview('value', '0'); ndv.getters.inputDataContainer().find('span').contains('input').realMouseDown(); @@ -350,19 +356,23 @@ describe('Data mapping', () => { workflowPage.actions.zoomToFit(); workflowPage.actions.openNode('Set'); - ndv.actions.clearParameterInput('value'); ndv.actions.typeIntoParameterInput('value', '='); - ndv.actions.typeIntoParameterInput('value', 'hello world{enter}{enter}newline'); + ndv.getters.inlineExpressionEditorInput().find('.cm-content').paste('hello world\n\nnewline'); + ndv.getters.inlineExpressionEditorInput().type('{esc}'); ndv.getters.inputDataContainer().should('exist').find('span').contains('count').realMouseDown(); - ndv.actions.mapToParameter('value'); + ndv.getters + .inlineExpressionEditorInput() + .should('have.text', '{{ $json.input[0].count }}hello worldnewline'); + ndv.getters.inlineExpressionEditorInput().type('{esc}'); + ndv.actions.validateExpressionPreview('value', '0hello world\n\nnewline'); ndv.getters.inputDataContainer().find('span').contains('input').realMouseDown(); - ndv.actions.mapToParameter('value', 'bottom'); + ndv.actions.mapToParameter('value', 'center'); ndv.getters .inlineExpressionEditorInput() - .should('have.text', '{{ $json.input[0].count }}hello worldnewline{{ $json.input }}'); + .should('have.text', '{{ $json.input[0].count }}hello world{{ $json.input }}newline'); }); }); diff --git a/cypress/e2e/33-settings-personal.cy.ts b/cypress/e2e/33-settings-personal.cy.ts index 372f14d231cd4..e3cc572c9ee90 100644 --- a/cypress/e2e/33-settings-personal.cy.ts +++ b/cypress/e2e/33-settings-personal.cy.ts @@ -36,13 +36,13 @@ describe('Personal Settings', () => { }); }); // eslint-disable-next-line n8n-local-rules/no-skipped-tests - it.skip('not allow malicious values for personal data', () => { + it('not allow malicious values for personal data', () => { cy.visit('/settings/personal'); INVALID_NAMES.forEach((name) => { cy.getByTestId('personal-data-form').find('input[name="firstName"]').clear().type(name); cy.getByTestId('personal-data-form').find('input[name="lastName"]').clear().type(name); cy.getByTestId('save-settings-button').click(); - errorToast().should('contain', 'Malicious firstName | Malicious lastName'); + errorToast().should('contain', 'Potentially malicious string | Potentially malicious string'); errorToast().find('.el-notification__closeBtn').click(); }); }); diff --git a/cypress/pages/ndv.ts b/cypress/pages/ndv.ts index 1a80d79707c6d..3bb9eb0fe0907 100644 --- a/cypress/pages/ndv.ts +++ b/cypress/pages/ndv.ts @@ -175,7 +175,7 @@ export class NDV extends BasePage { this.getters.editPinnedDataButton().click(); this.getters.pinnedDataEditor().click(); - this.getters.pinnedDataEditor().type('{selectall}{backspace}').paste(JSON.stringify(data)); + this.getters.pinnedDataEditor().invoke('text', '').paste(JSON.stringify(data)); this.actions.savePinnedData(); }, diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index 3968a09b5b0ba..4d5d7a7f9af75 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -17,6 +17,8 @@ beforeEach(() => { cy.window().then((win): void => { win.localStorage.setItem('N8N_THEME', 'light'); + win.localStorage.setItem('N8N_AUTOCOMPLETE_ONBOARDED', 'true'); + win.localStorage.setItem('N8N_MAPPING_ONBOARDED', 'true'); }); cy.intercept('GET', '/rest/settings', (req) => { diff --git a/packages/cli/src/validators/__tests__/no-url.validator.test.ts b/packages/cli/src/validators/__tests__/no-url.validator.test.ts index ead34019889e3..dafba595efcab 100644 --- a/packages/cli/src/validators/__tests__/no-url.validator.test.ts +++ b/packages/cli/src/validators/__tests__/no-url.validator.test.ts @@ -10,7 +10,7 @@ describe('NoUrl', () => { const entity = new Entity(); describe('URLs', () => { - const URLS = ['http://google.com', 'www.domain.tld']; + const URLS = ['http://google.com', 'www.domain.tld', 'n8n.io']; for (const str of URLS) { test(`should block ${str}`, async () => { diff --git a/packages/cli/src/validators/no-url.validator.ts b/packages/cli/src/validators/no-url.validator.ts index 1df05fed5fa0d..0cdacaddc185d 100644 --- a/packages/cli/src/validators/no-url.validator.ts +++ b/packages/cli/src/validators/no-url.validator.ts @@ -1,7 +1,7 @@ import type { ValidationOptions, ValidatorConstraintInterface } from 'class-validator'; import { registerDecorator, ValidatorConstraint } from 'class-validator'; -const URL_REGEX = /^(https?:\/\/|www\.)/i; +const URL_REGEX = /^(https?:\/\/|www\.)|(\.[\p{L}\d-]+)/iu; @ValidatorConstraint({ name: 'NoUrl', async: false }) class NoUrlConstraint implements ValidatorConstraintInterface {