test: Use nanoid instead of UUID in e2e tests for wf names (no-changelog) (#9717)

This commit is contained in:
Tomi Turtiainen 2024-06-13 09:39:53 +03:00 committed by GitHub
parent a9179896f6
commit 58f00bbacd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 77 additions and 74 deletions

View file

@ -1,6 +1,6 @@
import { v4 as uuid } from 'uuid';
import { WorkflowsPage as WorkflowsPageClass } from '../pages/workflows';
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
import { getUniqueWorkflowName } from '../utils/workflowUtils';
const WorkflowsPage = new WorkflowsPageClass();
const WorkflowPage = new WorkflowPageClass();
@ -16,7 +16,7 @@ describe('Workflows', () => {
WorkflowsPage.getters.newWorkflowButtonCard().should('be.visible');
WorkflowsPage.getters.newWorkflowButtonCard().click();
cy.createFixtureWorkflow('Test_workflow_1.json', `Empty State Card Workflow ${uuid()}`);
cy.createFixtureWorkflow('Test_workflow_1.json', 'Empty State Card Workflow');
WorkflowPage.getters.workflowTags().should('contain.text', 'some-tag-1');
WorkflowPage.getters.workflowTags().should('contain.text', 'some-tag-2');
@ -27,7 +27,7 @@ describe('Workflows', () => {
cy.visit(WorkflowsPage.url);
WorkflowsPage.getters.createWorkflowButton().click();
cy.createFixtureWorkflow('Test_workflow_2.json', `My New Workflow ${uuid()}`);
cy.createFixtureWorkflow('Test_workflow_2.json', getUniqueWorkflowName('My New Workflow'));
WorkflowPage.getters.workflowTags().should('contain.text', 'other-tag-1');
WorkflowPage.getters.workflowTags().should('contain.text', 'other-tag-2');

View file

@ -1,4 +1,3 @@
import { v4 as uuid } from 'uuid';
import { NDV, WorkflowPage as WorkflowPageClass } from '../pages';
import { successToast } from '../pages/notifications';
@ -11,7 +10,7 @@ describe('ADO-1338-ndv-missing-input-panel', () => {
});
it('should show the input and output panels when node is missing input and output data', () => {
cy.createFixtureWorkflow('Test_ado_1338.json', uuid());
cy.createFixtureWorkflow('Test_ado_1338.json');
// Execute the workflow
workflowPage.getters.zoomToFitButton().click();

View file

@ -1,4 +1,4 @@
import { v4 as uuid } from 'uuid';
import { nanoid } from 'nanoid';
import { WorkflowPage, NDV, CredentialsModal } from '../pages';
import { cowBase64 } from '../support/binaryTestFiles';
import { BACKEND_BASE_URL, EDIT_FIELDS_SET_NODE_NAME } from '../constants';
@ -81,28 +81,28 @@ describe('Webhook Trigger node', () => {
});
it('should listen for a GET request', () => {
simpleWebhookCall({ method: 'GET', webhookPath: uuid(), executeNow: true });
simpleWebhookCall({ method: 'GET', webhookPath: nanoid(), executeNow: true });
});
it('should listen for a POST request', () => {
simpleWebhookCall({ method: 'POST', webhookPath: uuid(), executeNow: true });
simpleWebhookCall({ method: 'POST', webhookPath: nanoid(), executeNow: true });
});
it('should listen for a DELETE request', () => {
simpleWebhookCall({ method: 'DELETE', webhookPath: uuid(), executeNow: true });
simpleWebhookCall({ method: 'DELETE', webhookPath: nanoid(), executeNow: true });
});
it('should listen for a HEAD request', () => {
simpleWebhookCall({ method: 'HEAD', webhookPath: uuid(), executeNow: true });
simpleWebhookCall({ method: 'HEAD', webhookPath: nanoid(), executeNow: true });
});
it('should listen for a PATCH request', () => {
simpleWebhookCall({ method: 'PATCH', webhookPath: uuid(), executeNow: true });
simpleWebhookCall({ method: 'PATCH', webhookPath: nanoid(), executeNow: true });
});
it('should listen for a PUT request', () => {
simpleWebhookCall({ method: 'PUT', webhookPath: uuid(), executeNow: true });
simpleWebhookCall({ method: 'PUT', webhookPath: nanoid(), executeNow: true });
});
it('should listen for a GET request and respond with Respond to Webhook node', () => {
const webhookPath = uuid();
const webhookPath = nanoid();
simpleWebhookCall({
method: 'GET',
webhookPath,
@ -130,7 +130,7 @@ describe('Webhook Trigger node', () => {
});
it('should listen for a GET request and respond custom status code 201', () => {
const webhookPath = uuid();
const webhookPath = nanoid();
simpleWebhookCall({
method: 'GET',
webhookPath,
@ -147,7 +147,7 @@ describe('Webhook Trigger node', () => {
});
it('should listen for a GET request and respond with last node', () => {
const webhookPath = uuid();
const webhookPath = nanoid();
simpleWebhookCall({
method: 'GET',
webhookPath,
@ -172,7 +172,7 @@ describe('Webhook Trigger node', () => {
});
it('should listen for a GET request and respond with last node binary data', () => {
const webhookPath = uuid();
const webhookPath = nanoid();
simpleWebhookCall({
method: 'GET',
webhookPath,
@ -213,7 +213,7 @@ describe('Webhook Trigger node', () => {
});
it('should listen for a GET request and respond with an empty body', () => {
const webhookPath = uuid();
const webhookPath = nanoid();
simpleWebhookCall({
method: 'GET',
webhookPath,
@ -232,7 +232,7 @@ describe('Webhook Trigger node', () => {
});
it('should listen for a GET request with Basic Authentication', () => {
const webhookPath = uuid();
const webhookPath = nanoid();
simpleWebhookCall({
method: 'GET',
webhookPath,
@ -275,7 +275,7 @@ describe('Webhook Trigger node', () => {
});
it('should listen for a GET request with Header Authentication', () => {
const webhookPath = uuid();
const webhookPath = nanoid();
simpleWebhookCall({
method: 'GET',
webhookPath,

View file

@ -1,4 +1,3 @@
import { v4 as uuid } from 'uuid';
import { NDV, WorkflowExecutionsTab, WorkflowPage as WorkflowPageClass } from '../pages';
import { SCHEDULE_TRIGGER_NODE_NAME, EDIT_FIELDS_SET_NODE_NAME } from '../constants';
import { errorToast, successToast } from '../pages/notifications';
@ -13,7 +12,7 @@ describe('Execution', () => {
});
it('should test manual workflow', () => {
cy.createFixtureWorkflow('Manual_wait_set.json', `Manual wait set ${uuid()}`);
cy.createFixtureWorkflow('Manual_wait_set.json');
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().should('be.visible');
@ -73,7 +72,7 @@ describe('Execution', () => {
});
it('should test manual workflow stop', () => {
cy.createFixtureWorkflow('Manual_wait_set.json', `Manual wait set ${uuid()}`);
cy.createFixtureWorkflow('Manual_wait_set.json');
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().should('be.visible');
@ -132,7 +131,7 @@ describe('Execution', () => {
});
it('should test webhook workflow', () => {
cy.createFixtureWorkflow('Webhook_wait_set.json', `Webhook wait set ${uuid()}`);
cy.createFixtureWorkflow('Webhook_wait_set.json');
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().should('be.visible');
@ -205,7 +204,7 @@ describe('Execution', () => {
});
it('should test webhook workflow stop', () => {
cy.createFixtureWorkflow('Webhook_wait_set.json', `Webhook wait set ${uuid()}`);
cy.createFixtureWorkflow('Webhook_wait_set.json');
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().should('be.visible');
@ -293,7 +292,7 @@ describe('Execution', () => {
describe('connections should be colored differently for pinned data', () => {
beforeEach(() => {
cy.createFixtureWorkflow('Schedule_pinned.json', `Schedule pinned ${uuid()}`);
cy.createFixtureWorkflow('Schedule_pinned.json');
workflowPage.actions.deselectAll();
workflowPage.getters.zoomToFitButton().click();
@ -492,10 +491,7 @@ describe('Execution', () => {
});
it('should send proper payload for node rerun', () => {
cy.createFixtureWorkflow(
'Multiple_trigger_node_rerun.json',
`Multiple trigger node rerun ${uuid()}`,
);
cy.createFixtureWorkflow('Multiple_trigger_node_rerun.json', 'Multiple trigger node rerun');
workflowPage.getters.zoomToFitButton().click();
workflowPage.getters.executeWorkflowButton().click();
@ -520,10 +516,7 @@ describe('Execution', () => {
});
it('should send proper payload for manual node run', () => {
cy.createFixtureWorkflow(
'Check_manual_node_run_for_pinned_and_rundata.json',
`Check manual node run for pinned and rundata ${uuid()}`,
);
cy.createFixtureWorkflow('Check_manual_node_run_for_pinned_and_rundata.json');
workflowPage.getters.zoomToFitButton().click();
@ -576,10 +569,7 @@ describe('Execution', () => {
});
it('should successfully execute partial executions with nodes attached to the second output', () => {
cy.createFixtureWorkflow(
'Test_Workflow_pairedItem_incomplete_manual_bug.json',
'My test workflow',
);
cy.createFixtureWorkflow('Test_Workflow_pairedItem_incomplete_manual_bug.json');
cy.intercept('POST', '/rest/workflows/**/run').as('workflowRun');
@ -599,10 +589,7 @@ describe('Execution', () => {
});
it('should execute workflow partially up to the node that has issues', () => {
cy.createFixtureWorkflow(
'Test_workflow_partial_execution_with_missing_credentials.json',
'My test workflow',
);
cy.createFixtureWorkflow('Test_workflow_partial_execution_with_missing_credentials.json');
cy.intercept('POST', '/rest/workflows/**/run').as('workflowRun');

View file

@ -1,4 +1,3 @@
import { v4 as uuid } from 'uuid';
import { WorkflowExecutionsTab, WorkflowPage as WorkflowPageClass } from '../pages';
import { BACKEND_BASE_URL } from '../constants';
@ -11,7 +10,7 @@ describe('ADO-2106 connections should be colored correctly for pinned data in ex
});
beforeEach(() => {
cy.createFixtureWorkflow('Webhook_set_pinned.json', `Webhook set pinned ${uuid()}`);
cy.createFixtureWorkflow('Webhook_set_pinned.json');
workflowPage.actions.deselectAll();
workflowPage.getters.zoomToFitButton().click();

View file

@ -1,4 +1,3 @@
import { v4 as uuid } from 'uuid';
import { WorkflowPage, NDV } from '../pages';
const workflowPage = new WorkflowPage();
@ -7,7 +6,7 @@ const ndv = new NDV();
describe('NDV', () => {
beforeEach(() => {
workflowPage.actions.visit();
workflowPage.actions.renameWorkflow(uuid());
workflowPage.actions.renameWithUniqueName();
workflowPage.actions.saveWorkflowOnButtonClick();
});

View file

@ -1,4 +1,3 @@
import { v4 as uuid } from 'uuid';
import { getVisibleSelect } from '../utils';
import { MANUAL_TRIGGER_NODE_DISPLAY_NAME } from '../constants';
import { NDV, WorkflowPage } from '../pages';
@ -13,7 +12,7 @@ const ndv = new NDV();
describe('NDV', () => {
beforeEach(() => {
workflowPage.actions.visit();
workflowPage.actions.renameWorkflow(uuid());
workflowPage.actions.renameWithUniqueName();
workflowPage.actions.saveWorkflowOnButtonClick();
});
@ -55,7 +54,7 @@ describe('NDV', () => {
});
it('should change input and go back to canvas', () => {
cy.createFixtureWorkflow('NDV-test-select-input.json', `NDV test select input ${uuid()}`);
cy.createFixtureWorkflow('NDV-test-select-input.json', 'NDV test select input');
workflowPage.actions.zoomToFit();
workflowPage.getters.canvasNodes().last().dblclick();
ndv.getters.inputSelect().click();
@ -157,7 +156,7 @@ describe('NDV', () => {
'prop2',
];
function setupSchemaWorkflow() {
cy.createFixtureWorkflow('Test_workflow_schema_test.json', `NDV test schema view ${uuid()}`);
cy.createFixtureWorkflow('Test_workflow_schema_test.json');
workflowPage.actions.zoomToFit();
workflowPage.actions.openNode('Set');
ndv.actions.execute();
@ -231,7 +230,7 @@ describe('NDV', () => {
it('should display large schema', () => {
cy.createFixtureWorkflow(
'Test_workflow_schema_test_pinned_data.json',
`NDV test schema view ${uuid()}`,
'NDV test schema view 2',
);
workflowPage.actions.zoomToFit();
workflowPage.actions.openNode('Set');
@ -306,7 +305,7 @@ describe('NDV', () => {
it('should display parameter hints correctly', () => {
workflowPage.actions.visit();
cy.createFixtureWorkflow('Test_workflow_3.json', 'My test workflow');
cy.createFixtureWorkflow('Test_workflow_3.json', 'My test workflow 1');
workflowPage.actions.openNode('Set1');
ndv.actions.typeIntoParameterInput('value', '='); // switch to expressions
@ -574,7 +573,7 @@ describe('NDV', () => {
});
it('should show node name and version in settings', () => {
cy.createFixtureWorkflow('Test_workflow_ndv_version.json', `NDV test version ${uuid()}`);
cy.createFixtureWorkflow('Test_workflow_ndv_version.json', 'NDV test version');
workflowPage.actions.openNode('Edit Fields (old)');
ndv.actions.openSettings();
@ -711,7 +710,7 @@ describe('NDV', () => {
};
cy.createFixtureWorkflow(
'open_node_creator_for_connection.json',
`open_node_creator_for_connection ${uuid()}`,
'open_node_creator_for_connection',
);
Object.entries(hintMapper).forEach(([node, group]) => {
@ -742,7 +741,7 @@ describe('NDV', () => {
it('should allow selecting item for expressions', () => {
workflowPage.actions.visit();
cy.createFixtureWorkflow('Test_workflow_3.json', 'My test workflow');
cy.createFixtureWorkflow('Test_workflow_3.json', 'My test workflow 2');
workflowPage.actions.openNode('Set');
ndv.actions.typeIntoParameterInput('value', '='); // switch to expressions

View file

@ -15,7 +15,6 @@
},
"devDependencies": {
"@types/lodash": "^4.14.195",
"@types/uuid": "^8.3.2",
"eslint-plugin-cypress": "^3.3.0",
"n8n-workflow": "workspace:*"
},
@ -26,7 +25,7 @@
"cypress-otp": "^1.0.3",
"cypress-real-events": "^1.12.0",
"lodash": "4.17.21",
"start-server-and-test": "^2.0.3",
"uuid": "8.3.2"
"nanoid": "3.3.6",
"start-server-and-test": "^2.0.3"
}
}

View file

@ -1,5 +1,6 @@
import { META_KEY } from '../constants';
import { getVisibleSelect } from '../utils';
import { getUniqueWorkflowName } from '../utils/workflowUtils';
import { BasePage } from './base';
import { NodeCreator } from './features/node-creator';
@ -311,6 +312,9 @@ export class WorkflowPage extends BasePage {
cy.get('body').type(newName);
cy.get('body').type('{enter}');
},
renameWithUniqueName: () => {
this.actions.renameWorkflow(getUniqueWorkflowName());
},
addTags: (tags: string | string[]) => {
if (!Array.isArray(tags)) tags = [tags];

View file

@ -59,10 +59,13 @@ switch (scenario) {
});
break;
case 'all':
const specSuiteFilter = process.argv[3];
const specParam = specSuiteFilter ? ` --spec **/*${specSuiteFilter}*` : '';
runTests({
startCommand: 'start',
url: 'http://localhost:5678/favicon.ico',
testCommand: 'cypress run --headless',
testCommand: `cypress run --headless ${specParam}`,
});
break;
default:

View file

@ -9,6 +9,7 @@ import {
INSTANCE_OWNER,
N8N_AUTH_COOKIE,
} from '../constants';
import { getUniqueWorkflowName } from '../utils/workflowUtils';
Cypress.Commands.add('setAppDate', (targetDate: number | Date) => {
cy.window().then((win) => {
@ -24,17 +25,22 @@ Cypress.Commands.add('getByTestId', (selector, ...args) => {
return cy.get(`[data-test-id="${selector}"]`, ...args);
});
Cypress.Commands.add('createFixtureWorkflow', (fixtureKey, workflowName) => {
const workflowPage = new WorkflowPage();
Cypress.Commands.add(
'createFixtureWorkflow',
(fixtureKey: string, workflowName = getUniqueWorkflowName()) => {
const workflowPage = new WorkflowPage();
// We need to force the click because the input is hidden
workflowPage.getters.workflowImportInput().selectFile(`fixtures/${fixtureKey}`, { force: true });
// We need to force the click because the input is hidden
workflowPage.getters
.workflowImportInput()
.selectFile(`fixtures/${fixtureKey}`, { force: true });
cy.waitForLoad(false);
workflowPage.actions.setWorkflowName(workflowName);
workflowPage.getters.saveButton().should('contain', 'Saved');
workflowPage.actions.zoomToFit();
});
cy.waitForLoad(false);
workflowPage.actions.setWorkflowName(workflowName);
workflowPage.getters.saveButton().should('contain', 'Saved');
workflowPage.actions.zoomToFit();
},
);
Cypress.Commands.add(
'findChildByTestId',

View file

@ -25,7 +25,13 @@ declare global {
...args: Array<Partial<Loggable & Timeoutable & Withinable & Shadow> | undefined>
): Chainable<JQuery<HTMLElement>>;
findChildByTestId(childTestId: string): Chainable<JQuery<HTMLElement>>;
createFixtureWorkflow(fixtureKey: string, workflowName: string): void;
/**
* Creates a workflow from the given fixture and optionally renames it.
*
* @param fixtureKey
* @param [workflowName] Optional name for the workflow. A random nanoid is used if not given
*/
createFixtureWorkflow(fixtureKey: string, workflowName?: string): void;
/** @deprecated */
signin(payload: SigninPayload): void;
signinAsOwner(): void;

View file

@ -0,0 +1,5 @@
import { nanoid } from 'nanoid';
export function getUniqueWorkflowName(workflowNamePrefix?: string) {
return workflowNamePrefix ? `${workflowNamePrefix} ${nanoid(12)}` : nanoid(12);
}

View file

@ -140,19 +140,16 @@ importers:
lodash:
specifier: 4.17.21
version: 4.17.21
nanoid:
specifier: 3.3.6
version: 3.3.6
start-server-and-test:
specifier: ^2.0.3
version: 2.0.3
uuid:
specifier: 8.3.2
version: 8.3.2
devDependencies:
'@types/lodash':
specifier: ^4.14.195
version: 4.14.195
'@types/uuid':
specifier: ^8.3.2
version: 8.3.4
eslint-plugin-cypress:
specifier: ^3.3.0
version: 3.3.0(eslint@8.57.0)