mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-02 07:01:30 -08:00
feat: Make use of db:reset in all test suites (no-changelog) (#4739)
* feat: Make use of db:reset in all test suites * refactor: Rename task to no longer use db: prefix * feat: wrap cypress tasks into commands * refactor: rename resetDatabase to resetAll * fix: update test:e2e:all to use --headless
This commit is contained in:
parent
aac207a947
commit
622118f983
|
@ -11,10 +11,10 @@ module.exports = defineConfig({
|
||||||
experimentalSessionAndOrigin: true,
|
experimentalSessionAndOrigin: true,
|
||||||
experimentalInteractiveRunEvents: true,
|
experimentalInteractiveRunEvents: true,
|
||||||
|
|
||||||
setupNodeEvents(on) {
|
setupNodeEvents(on, config) {
|
||||||
on('task', {
|
on('task', {
|
||||||
'db:reset': () => fetch(BASE_URL + '/e2e/db/reset', { method: 'POST' }),
|
'reset': () => fetch(BASE_URL + '/e2e/db/reset', { method: 'POST' }),
|
||||||
'db:setup-owner': (payload) =>
|
'setup-owner': (payload) =>
|
||||||
fetch(BASE_URL + '/e2e/db/setup-owner', {
|
fetch(BASE_URL + '/e2e/db/setup-owner', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
|
|
|
@ -8,21 +8,21 @@ const lastName = randLastName();
|
||||||
|
|
||||||
describe('Authentication', () => {
|
describe('Authentication', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.task('db:reset');
|
cy.resetAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should setup owner', () => {
|
it('should setup owner', () => {
|
||||||
cy.signup(email, firstName, lastName, password);
|
cy.setup({ email, firstName, lastName, password });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should sign user in', () => {
|
it('should sign user in', () => {
|
||||||
cy.task('db:setup-owner', { email, password, firstName, lastName });
|
cy.setupOwner({ email, password, firstName, lastName });
|
||||||
cy.on('uncaught:exception', (err, runnable) => {
|
cy.on('uncaught:exception', (err, runnable) => {
|
||||||
expect(err.message).to.include('Not logged in');
|
expect(err.message).to.include('Not logged in');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.signin(email, password);
|
cy.signin({ email, password });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { WorkflowsPage as WorkflowsPageClass } from '../pages/workflows';
|
||||||
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
|
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
const username = DEFAULT_USER_EMAIL;
|
const email = DEFAULT_USER_EMAIL;
|
||||||
const password = DEFAULT_USER_PASSWORD;
|
const password = DEFAULT_USER_PASSWORD;
|
||||||
const firstName = randFirstName();
|
const firstName = randFirstName();
|
||||||
const lastName = randLastName();
|
const lastName = randLastName();
|
||||||
|
@ -12,16 +12,19 @@ const WorkflowsPage = new WorkflowsPageClass();
|
||||||
const WorkflowPage = new WorkflowPageClass();
|
const WorkflowPage = new WorkflowPageClass();
|
||||||
|
|
||||||
describe('Workflows', () => {
|
describe('Workflows', () => {
|
||||||
beforeEach(() => {
|
before(() => {
|
||||||
cy.signup(username, firstName, lastName, password);
|
cy.resetAll();
|
||||||
|
cy.setup({ email, firstName, lastName, password });
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
cy.on('uncaught:exception', (err, runnable) => {
|
cy.on('uncaught:exception', (err, runnable) => {
|
||||||
expect(err.message).to.include('Not logged in');
|
expect(err.message).to.include('Not logged in');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.signin(username, password);
|
cy.signin({ email, password });
|
||||||
cy.visit(WorkflowsPage.url);
|
cy.visit(WorkflowsPage.url);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { DEFAULT_USER_EMAIL, DEFAULT_USER_PASSWORD } from "../constants";
|
||||||
import { randFirstName, randLastName } from "@ngneat/falso";
|
import { randFirstName, randLastName } from "@ngneat/falso";
|
||||||
import { CredentialsPage, CredentialsModal } from '../pages';
|
import { CredentialsPage, CredentialsModal } from '../pages';
|
||||||
|
|
||||||
const username = DEFAULT_USER_EMAIL;
|
const email = DEFAULT_USER_EMAIL;
|
||||||
const password = DEFAULT_USER_PASSWORD;
|
const password = DEFAULT_USER_PASSWORD;
|
||||||
const firstName = randFirstName();
|
const firstName = randFirstName();
|
||||||
const lastName = randLastName();
|
const lastName = randLastName();
|
||||||
|
@ -11,20 +11,18 @@ const credentialsModal = new CredentialsModal();
|
||||||
|
|
||||||
describe('Credentials', () => {
|
describe('Credentials', () => {
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.task('db:reset');
|
cy.resetAll();
|
||||||
Cypress.session.clearAllSavedSessions();
|
cy.setup({ email, firstName, lastName, password });
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.signup(username, firstName, lastName, password);
|
|
||||||
|
|
||||||
cy.on('uncaught:exception', (err, runnable) => {
|
cy.on('uncaught:exception', (err, runnable) => {
|
||||||
expect(err.message).to.include('Not logged in');
|
expect(err.message).to.include('Not logged in');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.signin(username, password);
|
cy.signin({ email, password });
|
||||||
cy.visit(credentialsPage.url);
|
cy.visit(credentialsPage.url);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ const settingsUsersPage = new SettingsUsersPage();
|
||||||
|
|
||||||
const messageBox = new MessageBox();
|
const messageBox = new MessageBox();
|
||||||
|
|
||||||
const username = DEFAULT_USER_EMAIL;
|
const email = DEFAULT_USER_EMAIL;
|
||||||
const password = DEFAULT_USER_PASSWORD;
|
const password = DEFAULT_USER_PASSWORD;
|
||||||
const firstName = randFirstName();
|
const firstName = randFirstName();
|
||||||
const lastName = randLastName();
|
const lastName = randLastName();
|
||||||
|
@ -27,7 +27,7 @@ describe('Default owner', () => {
|
||||||
// todo test should redirect to setup if have not skipped
|
// todo test should redirect to setup if have not skipped
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.task('db:reset');
|
cy.resetAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to use n8n without user management and setup UM', () => {
|
it('should be able to use n8n without user management and setup UM', () => {
|
||||||
|
@ -83,7 +83,7 @@ describe('Default owner', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should be able to setup instance and migrate workflows and credentials', () => {
|
describe('should be able to setup instance and migrate workflows and credentials', () => {
|
||||||
cy.signup(username, firstName, lastName, password);
|
cy.setup({ email, firstName, lastName, password });
|
||||||
|
|
||||||
messageBox.getters.content().should('contain.text', '1 existing workflow and 1 credential')
|
messageBox.getters.content().should('contain.text', '1 existing workflow and 1 credential')
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ const WorkflowsPage = new WorkflowsPageClass();
|
||||||
const WorkflowPage = new WorkflowPageClass();
|
const WorkflowPage = new WorkflowPageClass();
|
||||||
|
|
||||||
describe('HTTP Request node', () => {
|
describe('HTTP Request node', () => {
|
||||||
beforeEach(() => {
|
before(() => {
|
||||||
cy.task('db:reset');
|
cy.resetAll();
|
||||||
cy.skipSetup();
|
cy.skipSetup();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,24 @@
|
||||||
import { NodeCreator } from '../pages/features/node-creator';
|
import { NodeCreator } from '../pages/features/node-creator';
|
||||||
import { INodeTypeDescription } from '../../packages/workflow';
|
import { INodeTypeDescription } from '../../packages/workflow';
|
||||||
import CustomNodeFixture from '../fixtures/Custom_node.json';
|
import CustomNodeFixture from '../fixtures/Custom_node.json';
|
||||||
|
import {DEFAULT_USER_EMAIL, DEFAULT_USER_PASSWORD} from "../constants";
|
||||||
|
import {randFirstName, randLastName} from "@ngneat/falso";
|
||||||
|
|
||||||
|
const email = DEFAULT_USER_EMAIL;
|
||||||
|
const password = DEFAULT_USER_PASSWORD;
|
||||||
|
const firstName = randFirstName();
|
||||||
|
const lastName = randLastName();
|
||||||
const nodeCreatorFeature = new NodeCreator();
|
const nodeCreatorFeature = new NodeCreator();
|
||||||
|
|
||||||
describe('Node Creator', () => {
|
describe('Node Creator', () => {
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.task('db:reset');
|
cy.resetAll();
|
||||||
})
|
cy.setup({ email, firstName, lastName, password });
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
cy.signin({ email, password });
|
||||||
|
|
||||||
cy.intercept('GET', '/types/nodes.json', (req) => {
|
cy.intercept('GET', '/types/nodes.json', (req) => {
|
||||||
// Delete caching headers so that we can intercept the request
|
// Delete caching headers so that we can intercept the request
|
||||||
['etag', 'if-none-match', 'if-modified-since'].forEach(header => {delete req.headers[header]});
|
['etag', 'if-none-match', 'if-modified-since'].forEach(header => {delete req.headers[header]});
|
||||||
|
@ -21,7 +30,8 @@ describe('Node Creator', () => {
|
||||||
nodes.push(CustomNodeFixture as INodeTypeDescription);
|
nodes.push(CustomNodeFixture as INodeTypeDescription);
|
||||||
res.send(nodes)
|
res.send(nodes)
|
||||||
})
|
})
|
||||||
}).as('nodesIntercept')
|
}).as('nodesIntercept');
|
||||||
|
|
||||||
cy.visit(nodeCreatorFeature.url);
|
cy.visit(nodeCreatorFeature.url);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,22 +6,26 @@ const NEW_WORKFLOW_NAME = 'Something else';
|
||||||
const MANUAL_TRIGGER_NODE_NAME = 'Manual Trigger';
|
const MANUAL_TRIGGER_NODE_NAME = 'Manual Trigger';
|
||||||
const SCHEDULE_TRIGGER_NODE_NAME = 'Schedule Trigger';
|
const SCHEDULE_TRIGGER_NODE_NAME = 'Schedule Trigger';
|
||||||
|
|
||||||
const username = DEFAULT_USER_EMAIL;
|
const email = DEFAULT_USER_EMAIL;
|
||||||
const password = DEFAULT_USER_PASSWORD;
|
const password = DEFAULT_USER_PASSWORD;
|
||||||
const firstName = randFirstName();
|
const firstName = randFirstName();
|
||||||
const lastName = randLastName();
|
const lastName = randLastName();
|
||||||
const WorkflowPage = new WorkflowPageClass();
|
const WorkflowPage = new WorkflowPageClass();
|
||||||
|
|
||||||
describe('Workflow Actions', () => {
|
describe('Workflow Actions', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.resetAll();
|
||||||
|
cy.setup({ email, firstName, lastName, password });
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.signup(username, firstName, lastName, password);
|
|
||||||
cy.on('uncaught:exception', (err, runnable) => {
|
cy.on('uncaught:exception', (err, runnable) => {
|
||||||
expect(err.message).to.include('Not logged in');
|
expect(err.message).to.include('Not logged in');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.signin(username, password);
|
cy.signin({ email, password });
|
||||||
|
|
||||||
WorkflowPage.actions.visit();
|
WorkflowPage.actions.visit();
|
||||||
});
|
});
|
||||||
|
|
|
@ -52,7 +52,7 @@ Cypress.Commands.add('findChildByTestId', { prevSubject: true }, (subject: Cypre
|
||||||
|
|
||||||
Cypress.Commands.add(
|
Cypress.Commands.add(
|
||||||
'signin',
|
'signin',
|
||||||
(email, password) => {
|
({ email, password }) => {
|
||||||
const signinPage = new SigninPage();
|
const signinPage = new SigninPage();
|
||||||
const workflowsPage = new WorkflowsPage();
|
const workflowsPage = new WorkflowsPage();
|
||||||
|
|
||||||
|
@ -75,8 +75,7 @@ Cypress.Commands.add(
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// todo rename to setup
|
Cypress.Commands.add('setup', ({ email, firstName, lastName, password }) => {
|
||||||
Cypress.Commands.add('signup', (email, firstName, lastName, password) => {
|
|
||||||
const signupPage = new SignupPage();
|
const signupPage = new SignupPage();
|
||||||
|
|
||||||
cy.visit(signupPage.url);
|
cy.visit(signupPage.url);
|
||||||
|
@ -120,3 +119,12 @@ Cypress.Commands.add('skipSetup', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Cypress.Commands.add('resetAll', () => {
|
||||||
|
cy.task('reset');
|
||||||
|
Cypress.session.clearAllSavedSessions();
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('setupOwner', (payload) => {
|
||||||
|
cy.task('setup-owner', payload);
|
||||||
|
});
|
||||||
|
|
|
@ -1,16 +1,29 @@
|
||||||
// Load type definitions that come with Cypress module
|
// Load type definitions that come with Cypress module
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
interface SigninPayload {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SetupPayload {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace Cypress {
|
namespace Cypress {
|
||||||
interface Chainable {
|
interface Chainable {
|
||||||
getByTestId(selector: string, ...args: (Partial<Loggable & Timeoutable & Withinable & Shadow> | undefined)[]): Chainable<JQuery<HTMLElement>>
|
getByTestId(selector: string, ...args: (Partial<Loggable & Timeoutable & Withinable & Shadow> | undefined)[]): Chainable<JQuery<HTMLElement>>
|
||||||
findChildByTestId(childTestId: string): Chainable<JQuery<HTMLElement>>
|
findChildByTestId(childTestId: string): Chainable<JQuery<HTMLElement>>
|
||||||
createFixtureWorkflow(fixtureKey: string, workflowName: string): void;
|
createFixtureWorkflow(fixtureKey: string, workflowName: string): void;
|
||||||
signin(email: string, password: string): void;
|
signin(payload: SigninPayload): void;
|
||||||
// todo: rename to setup
|
setup(payload: SetupPayload): void;
|
||||||
signup(email: string, firstName: string, lastName: string, password: string): void;
|
setupOwner(payload: SetupPayload): void;
|
||||||
skipSetup(): void;
|
skipSetup(): void;
|
||||||
|
resetAll(): void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
"test:e2e:ui": "cross-env E2E_TESTS=true start-server-and-test start http://localhost:5678/favicon.ico 'cypress open'",
|
"test:e2e:ui": "cross-env E2E_TESTS=true start-server-and-test start http://localhost:5678/favicon.ico 'cypress open'",
|
||||||
"test:e2e:dev": "cross-env E2E_TESTS=true CYPRESS_BASE_URL=http://localhost:8080 start-server-and-test dev http://localhost:8080/favicon.ico 'cypress open'",
|
"test:e2e:dev": "cross-env E2E_TESTS=true CYPRESS_BASE_URL=http://localhost:8080 start-server-and-test dev http://localhost:8080/favicon.ico 'cypress open'",
|
||||||
"test:e2e:smoke": "cross-env E2E_TESTS=true start-server-and-test start http://localhost:5678/favicon.ico 'cypress run --headless --spec \"cypress/e2e/0-smoke.cy.ts\"'",
|
"test:e2e:smoke": "cross-env E2E_TESTS=true start-server-and-test start http://localhost:5678/favicon.ico 'cypress run --headless --spec \"cypress/e2e/0-smoke.cy.ts\"'",
|
||||||
"test:e2e:all": "cross-env E2E_TESTS=true start-server-and-test start http://localhost:5678/favicon.ico 'cypress run'"
|
"test:e2e:all": "cross-env E2E_TESTS=true start-server-and-test start http://localhost:5678/favicon.ico 'cypress run --headless'"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"n8n": "*"
|
"n8n": "*"
|
||||||
|
|
Loading…
Reference in a new issue