Skip to content
Open
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
36 changes: 36 additions & 0 deletions frontend/packages/volto-workflow-manager/cypress.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const { defineConfig } = require('cypress');

module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
supportFile: 'cypress/support/e2e.js',
viewportWidth: 1280,
viewportHeight: 720,
video: false,
screenshotOnRunFailure: true,
retries: {
runMode: 2,
openMode: 0,
},
defaultCommandTimeout: 10000,
requestTimeout: 10000,
responseTimeout: 10000,
env: {
API_PATH: 'http://localhost:8080',
BACKEND_HOST: 'localhost',
BACKEND_PORT: 8080,
WORKFLOW_MANAGER_URL: '/controlpanel/workflowmanager',
},
setupNodeEvents(on, config) {
// implement node event listeners here
on('task', {
log(message) {
// eslint-disable-next-line no-console
console.log(message);
return null;
},
});
},
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
function randomString(length = 5) {
const chars = 'abcdefghijklmnopqrstuvwxyz';
return Array.from({ length }, () =>
chars.charAt(Math.floor(Math.random() * chars.length)),
).join('');
}

describe('Workflow Manager - Add State', () => {
before(() => {
cy.createTestWorkflow();
});

beforeEach(() => {
cy.goToTestWorkflow();
});

it('should add a new state to the workflow', () => {
cy.contains('button', 'Add State').click();

cy.get('[role="dialog"]').should('be.visible');

cy.get('[role="dialog"]').within(() => {
const stateName = `test-state-${randomString(5)}`;
cy.get('[aria-label="State name"]').type(stateName);

cy.get('[aria-label="State description"]').type('Test state description');

cy.contains('button', 'Add State').click();
});

cy.get('[role="dialog"]').should('not.exist');

cy.get('body').should('contain', 'test-state-');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
function randomString(length = 5) {
const chars = 'abcdefghijklmnopqrstuvwxyz';
return Array.from({ length }, () =>
chars.charAt(Math.floor(Math.random() * chars.length)),
).join('');
}

describe('Workflow Manager - Add Transition', () => {
before(() => {
cy.createTestWorkflow();
});

beforeEach(() => {
cy.goToTestWorkflow();
});

it('should add a new transition to the workflow', () => {
cy.contains('button', 'Add Transition').click();

cy.get('[role="dialog"]').should('be.visible');

cy.get('[role="dialog"]').within(() => {
cy.get(
'[aria-label="Select the destination state for the transition"]',
).click();
});

cy.get('[role="option"]').first().click();

cy.get('[role="dialog"]').within(() => {
const transitionName = `test-transition-${randomString(5)}`;
cy.get('[aria-label="New transition name"]').type(transitionName);

cy.get('[aria-label="Transition description"]').type(
'Test transition description',
);

cy.contains('button', 'Add Transition').click();
});

cy.wait(3000);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
describe('Workflow Manager - Assign Workflow', () => {
before(() => {
cy.createTestWorkflow();
});

beforeEach(() => {
cy.goToTestWorkflow();
});

it('should assign workflow to content types', () => {
cy.wait(3000);

cy.contains('button', 'Assign').click();

cy.get('[role="dialog"]').should('be.visible');

cy.get('[role="dialog"]').within(() => {
cy.contains('button', 'Select').click();
});

cy.get('[role="option"]').first().click();

cy.get('[role="dialog"]').within(() => {
cy.contains('button', 'Assign').should('not.be.disabled').click();
});

cy.get('[role="dialog"]').should('not.exist');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
function randomString(length = 5) {
const chars = 'abcdefghijklmnopqrstuvwxyz';
return Array.from({ length }, () =>
chars.charAt(Math.floor(Math.random() * chars.length)),
).join('');
}

describe('Workflow Manager - Create Workflow', () => {
beforeEach(() => {
cy.loginAsAdmin();
cy.goToWorkflowManager();
});

it('should create a new workflow by cloning a base workflow', () => {
cy.wait(2000);

cy.get('#toolbar-add-workflow').should('exist').scrollIntoView();

cy.get('#toolbar-add-workflow').click({ force: true });

cy.get('[role="dialog"]').should('be.visible');

cy.get('[role="dialog"]').within(() => {
const workflowName = `test-workflow-${randomString(5)}`;

cy.get('[aria-label="New workflow name"]').type(workflowName);

cy.get('[aria-label="Select a workflow to clone from"]').should(
'be.visible',
);
cy.get('[aria-label="Select a workflow to clone from"]').click();
});

cy.get('[role="option"]').first().click();

cy.get('[role="dialog"]').within(() => {
cy.contains('button', 'Add').should('not.be.disabled').click();
});

cy.url().should('include', 'workflow=');

cy.get('#toolbar-saving-workflow').should('exist');
});

it('should handle dialog cancellation', () => {
cy.wait(2000);

cy.get('#toolbar-add-workflow').should('exist').scrollIntoView();
cy.get('#toolbar-add-workflow').click({ force: true });

cy.get('[role="dialog"]').should('be.visible');

cy.get('[role="dialog"]').within(() => {
cy.contains('button', 'Cancel').click();
});

cy.get('[role="dialog"]').should('not.exist');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
describe('Workflow Manager - Delete Workflow', () => {
before(() => {
cy.createTestWorkflow();
});

beforeEach(() => {
cy.goToTestWorkflow();
});

it('should delete a workflow from the workflow table', () => {
cy.visit('/controlpanel/workflowmanager');
cy.wait(3000);

cy.get('[aria-label="Workflow table"]').should('be.visible');

cy.readFile('cypress/fixtures/test-workflow-id.json').then((data) => {
const workflowName = data.workflowName || data.workflowId;

cy.get('[aria-label="Workflow table"]').within(() => {
cy.contains('[role="row"]', workflowName).within(() => {
cy.get('[aria-label="Workflow actions"]').click();
});
});

cy.get('[role="menu"]').within(() => {
cy.contains('Delete').click();
});

cy.get('[role="dialog"]').should('be.visible');
cy.get('[role="dialog"]').within(() => {
cy.contains('button', 'Delete').click();
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
describe('Workflow Manager - Sanity Check', () => {
before(() => {
cy.createTestWorkflow();
});

beforeEach(() => {
cy.goToTestWorkflow();
});

it('should run sanity check and view results', () => {
cy.contains('button', 'Sanity Check', { timeout: 3000 })
.should('be.visible')
.click();

cy.contains('button', 'View Validation Results', {
timeout: 3000,
})
.should('be.visible')
.click();

cy.get('[role="alertdialog"]', { timeout: 3000 }).should('be.visible');

cy.get('[role="alertdialog"]').within(() => {
cy.contains('Validation Results').should('be.visible');

cy.contains('button', 'Close').click();
});

cy.get('[role="alertdialog"]').should('not.exist');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Custom commands for Workflow Manager e2e testing

Cypress.Commands.add(
'loginAsAdmin',
(username = 'admin', password = 'admin') => {
cy.visit('/login');

cy.get(
'input[name="login"], input[name="__ac_name"], input[id="login-name"]',
)
.first()
.type(username);

cy.get(
'input[name="password"], input[name="__ac_password"], input[type="password"]',
)
.first()
.type(password);

cy.get(
'input[type="submit"], button[type="submit"], button:contains("Log in")',
)
.first()
.click();

cy.url().should('not.include', '/login');
},
);

Cypress.Commands.add('goToWorkflowManager', () => {
cy.visit('/controlpanel/workflowmanager');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Import commands.js using ES2015 syntax:
import './commands'
import './workflow-setup'
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
function randomString(length = 5) {
const chars = 'abcdefghijklmnopqrstuvwxyz';
return Array.from({ length }, () =>
chars.charAt(Math.floor(Math.random() * chars.length)),
).join('');
}

Cypress.Commands.add('createTestWorkflow', () => {
cy.loginAsAdmin();
cy.goToWorkflowManager();

cy.wait(2000);

cy.get('#toolbar-add-workflow')
.should('exist')
.scrollIntoView()
.click({ force: true });

cy.get('[role="dialog"]').should('be.visible');
cy.wait(1000);

const workflowName = `test-workflow-${randomString(8)}`;

cy.get('[role="dialog"]').within(() => {
cy.get('[aria-label="New workflow name"]')
.should('be.visible')
.clear()
.type(workflowName);

cy.get('[aria-label="Select a workflow to clone from"]')
.should('be.visible')
.click();
});

cy.get('[role="option"]').first().click();

cy.get('[role="dialog"]').within(() => {
cy.contains('button', 'Add')
.should('not.be.disabled')
.should('be.visible')
.click();
});

cy.url().should('include', 'workflow=');

cy.url().then((url) => {
const workflowParam = url.split('workflow=')[1];
if (workflowParam) {
cy.writeFile('cypress/fixtures/test-workflow-id.json', {
workflowId: workflowParam,
workflowName: workflowName,
});
}
});

cy.get('#toolbar-saving-workflow').should('exist');
cy.log(`Created test workflow: ${workflowName}`);
});

Cypress.Commands.add('goToTestWorkflow', () => {
cy.readFile('cypress/fixtures/test-workflow-id.json').then((data) => {
if (!data || !data.workflowId) {
throw new Error(
'No test workflow found. Make sure createTestWorkflow was called first.',
);
}

cy.log(
`Navigating to test workflow: ${data.workflowName || data.workflowId}`,
);
cy.visit(`/controlpanel/workflowmanager?workflow=${data.workflowId}`);
});

cy.wait(1000);

cy.url().should('include', 'workflowmanager');
cy.url().should('include', 'workflow=');
});
Loading
Loading