Skip to content

Commit d12ee7d

Browse files
committed
# This is a combination of 5 commits.
# This is the 1st commit message: updated system tests # This is the commit message #2: system tests updated for linting # This is the commit message #3: Allow system tests to be run manually # This is the commit message #4: run for this branch # This is the commit message #5: add multitenency to system tests trigger
1 parent 9549767 commit d12ee7d

6 files changed

Lines changed: 207 additions & 23 deletions

File tree

.github/workflows/system-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ on:
55
push:
66
branches:
77
- main
8+
- multitenancy
89
- develop
910
- feature/**
1011

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/// <reference types="cypress" />
2+
import { OVERDUE } from '../../utils/selectors.utils';
3+
import { createChangeRequest } from '../../utils/change-request.utils.cy';
4+
5+
import { VISIBLE, INCLUDE } from '../../utils/cypress-actions.utils';
6+
7+
describe('Home Page', () => {
8+
beforeEach(() => {
9+
cy.login('Thomas Emrax', '/home');
10+
});
11+
12+
it('Displays Welcome Message', () => {
13+
cy.contains('Welcome, Thomas!').should(VISIBLE);
14+
});
15+
16+
it('Displays Change Requests To Review Section', () => {
17+
cy.contains('Change Requests To Review').should(VISIBLE);
18+
cy.contains('Change Request #').should(VISIBLE);
19+
});
20+
21+
it('Displays Overdue Work Packages Section', () => {
22+
cy.contains(OVERDUE).should(VISIBLE);
23+
});
24+
25+
it('Overdue Work Packages Contains At Least One Entry', () => {
26+
cy.contains('Impact Attenuator').should(VISIBLE);
27+
});
28+
29+
it('Can Navigate to Change Requests Page via Sidebar', () => {
30+
cy.get('a[href="/change-requests"]').first().click({ force: true });
31+
cy.url().should(INCLUDE, '/change-requests');
32+
});
33+
34+
it('Creating a CR Shows Up on Home Page', () => {
35+
const whatText = 'home page e2e test cr';
36+
37+
// Navigate to new CR form
38+
cy.visit(Cypress.env('base_url') + '/change-requests/new');
39+
cy.waitForLoading();
40+
41+
// Create the CR
42+
createChangeRequest({ what: whatText });
43+
44+
// Navigate back to home
45+
cy.visit(Cypress.env('base_url') + '/home');
46+
cy.waitForLoading();
47+
48+
// Verify the new CR appears somewhere on the home page (in My Un-reviewed section on CR overview,
49+
// which is also reflected in the home page CR count)
50+
cy.contains('Change Requests To Review').should(VISIBLE);
51+
});
52+
});
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/// <reference types="cypress" />
2+
import { NEW_PROJECT_BUTTON, ALL_PROJECTS_TAB, MY_TEAMS_PROJECTS, PROJECTS_IM_LEADING } from '../../utils/selectors.utils';
3+
4+
import { VISIBLE, LENGTH_GREATER_THAN, INCLUDE } from '../../utils/cypress-actions.utils';
5+
6+
describe('Projects Overview', () => {
7+
beforeEach(() => {
8+
cy.login('Thomas Emrax', '/projects');
9+
});
10+
11+
it("My Team's Projects Should Display At Least One Project", () => {
12+
cy.contains(MY_TEAMS_PROJECTS).should(VISIBLE);
13+
cy.contains(MY_TEAMS_PROJECTS).parent().parent().find('a').should(LENGTH_GREATER_THAN, 0);
14+
});
15+
16+
it("Projects I'm Leading Should Display At Least One Project", () => {
17+
cy.contains(PROJECTS_IM_LEADING).should(VISIBLE);
18+
cy.contains(PROJECTS_IM_LEADING).parent().parent().find('a').should(LENGTH_GREATER_THAN, 0);
19+
});
20+
21+
it('Can Switch to All Projects Table', () => {
22+
cy.contains(ALL_PROJECTS_TAB).click();
23+
cy.url().should(INCLUDE, '/projects/all');
24+
cy.get('[role="grid"]').should(VISIBLE);
25+
cy.contains('Impact Attenuator').should(VISIBLE);
26+
cy.contains('Bodywork').should(VISIBLE);
27+
});
28+
29+
it('Creating a Project Writes to DB and Appears in All Projects', () => {
30+
const projectName = 'E2E Test Project';
31+
32+
// Click New Project
33+
cy.contains(NEW_PROJECT_BUTTON).click();
34+
cy.url().should(INCLUDE, '/projects/new');
35+
36+
// Fill in Project Name
37+
cy.get('[placeholder="Enter project name..."]').type(projectName);
38+
39+
// Car is pre-selected (Miles), keep default
40+
41+
// Select a Team
42+
// Target the Teams label (not the sidebar link) and find its sibling combobox
43+
cy.get('label').contains('Teams').parent().find('[role="combobox"]').click({ force: true });
44+
cy.get('[role="listbox"]').contains('Huskies').click();
45+
46+
// Close any open dropdowns
47+
cy.get('body').click(0, 0);
48+
49+
// Fill in Summary
50+
cy.get('[placeholder="Enter a summary..."]').type('An e2e test project for automated testing', { force: true });
51+
52+
// Submit
53+
cy.contains('Submit').click({ force: true });
54+
55+
// Should redirect to All Projects
56+
cy.url().should(INCLUDE, '/projects/all');
57+
58+
// Verify the project appears in the table
59+
cy.contains(projectName, { timeout: 10000 }).should(VISIBLE);
60+
});
61+
});
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/// <reference types="cypress" />
2+
/* eslint-disable no-undef */
3+
4+
const dismissAlerts = () => {
5+
// Remove all scheduling conflict alert banners from DOM directly
6+
cy.window().then((win) => {
7+
win.document.querySelectorAll('[role="alert"]').forEach((alert) => {
8+
alert.remove();
9+
});
10+
});
11+
};
12+
13+
const openCreateTaskModal = () => {
14+
dismissAlerts();
15+
cy.contains('button', 'New Event').click({ force: true });
16+
cy.get('[role="dialog"]', { timeout: 10000 }).should('exist');
17+
cy.get('[role="dialog"]').contains('button', 'Create Task').click({ force: true });
18+
cy.get('[role="dialog"]').find('h2').should('contain', 'Create Task');
19+
};
20+
21+
describe('Create Task', () => {
22+
beforeEach(() => {
23+
cy.login('Thomas Emrax', '/calendar');
24+
});
25+
26+
it('Can Open Create Task Modal from Calendar', () => {
27+
openCreateTaskModal();
28+
29+
// Verify the Create Task modal is open with expected fields
30+
cy.get('[role="dialog"]').contains('Project').should('exist');
31+
cy.get('[role="dialog"]').contains('Title').should('exist');
32+
cy.get('[role="dialog"]').contains('Priority').should('exist');
33+
cy.get('[role="dialog"]').contains('Status').should('exist');
34+
});
35+
36+
it('Creating a Task Writes to DB and Appears on Calendar', () => {
37+
const taskTitle = 'E2E Test Task';
38+
39+
openCreateTaskModal();
40+
41+
// Select a project
42+
cy.get('[role="dialog"]').find('input[placeholder="Select a project"]').click({ force: true });
43+
cy.get('[role="listbox"]').contains('Impact Attenuator').first().click();
44+
45+
// Fill in the title - the title textbox has no placeholder, find it via the Title label
46+
cy.get('[role="dialog"]').contains('Title').siblings().find('input').first().type(taskTitle, { force: true });
47+
48+
// Submit the form and verify the POST succeeds with the task title in the response
49+
cy.intercept('POST', '**/tasks/**').as('createTask');
50+
cy.get('[role="dialog"]').find('button').contains('Create').click({ force: true });
51+
cy.wait('@createTask').then((interception) => {
52+
expect(interception.response.statusCode).to.eq(200);
53+
expect(interception.response.body.title).to.eq(taskTitle);
54+
});
55+
});
56+
57+
it('Creating a Task with Assignee Writes to DB Successfully', () => {
58+
const taskTitle = 'Assigned Task Test';
59+
60+
openCreateTaskModal();
61+
62+
// Select a project
63+
cy.get('[role="dialog"]').find('input[placeholder="Select a project"]').click({ force: true });
64+
cy.get('[role="listbox"]').contains('Impact Attenuator').first().click();
65+
66+
// Fill in the title
67+
cy.get('[role="dialog"]').contains('Title').siblings().find('input').first().type(taskTitle, { force: true });
68+
69+
// Add self as assignee
70+
cy.get('[role="dialog"]').find('input[placeholder="Select users"]').click({ force: true });
71+
cy.get('[role="listbox"]').contains('Thomas Emrax').click();
72+
// Close the assignee dropdown by clicking elsewhere in the dialog
73+
cy.get('[role="dialog"]').find('h2').click({ force: true });
74+
75+
// Submit and verify the POST succeeds with correct data
76+
cy.intercept('POST', '**/tasks/**').as('createTask');
77+
cy.get('[role="dialog"]').find('button').contains('Create').click({ force: true });
78+
cy.wait('@createTask').then((interception) => {
79+
expect(interception.response.statusCode).to.eq(200);
80+
expect(interception.response.body.title).to.eq(taskTitle);
81+
expect(interception.response.body.assignees).to.have.length.greaterThan(0);
82+
});
83+
});
84+
});

system-tests/cypress/utils/change-request.utils.cy.js

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@ import {
1414
SUBMIT_BUTTON,
1515
CR_ROW,
1616
WHY_TYPE_OPTION,
17-
ADD_REASON,
18-
ACTIONS_BUTTON,
19-
ACTIONS_BUTTON_DELETE,
20-
CONFIRM_DELETE_TEXT_INPUT
17+
ADD_REASON
2118
} from './selectors.utils';
2219
import { INCLUDE } from './cypress-actions.utils';
2320

@@ -78,24 +75,7 @@ export const createChangeRequest = ({
7875

7976
cy.contains(SUBMIT_BUTTON).click();
8077
cy.url().should(INCLUDE, '/change-requests');
81-
cy.get(CR_ROW('My Un-reviewed Change Requests')).children().first().find('h6').contains('Change Request').click();
8278

83-
cy.contains(what);
84-
whys.forEach((why) => {
85-
cy.contains(why.description);
86-
cy.contains(why.type);
87-
});
88-
psArguments.forEach((argument) => {
89-
cy.contains(argument.budgetImpact);
90-
cy.contains(argument.description);
91-
cy.contains(argument.scopeImpact);
92-
cy.contains(argument.timelineImpact + ' weeks');
93-
});
94-
95-
const crId = 22; // Get this value from the UI. Could not figure out the CRID for some reason
96-
97-
cy.contains(ACTIONS_BUTTON).click();
98-
cy.contains(ACTIONS_BUTTON_DELETE).click();
99-
cy.get(CONFIRM_DELETE_TEXT_INPUT).type(crId);
100-
cy.contains(SUBMIT_BUTTON).click();
79+
// Verify the created CR appears in My Un-reviewed Change Requests
80+
cy.get(CR_ROW('My Un-reviewed Change Requests')).contains('Change Request').should('exist');
10181
};

system-tests/cypress/utils/selectors.utils.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ const SELECTORS = {
1818
TEAMS: 'Teams',
1919
OVERDUE: 'All Overdue Work Packages',
2020

21+
// Projects Page
22+
NEW_PROJECT_BUTTON: 'New Project',
23+
ALL_PROJECTS_TAB: 'All Projects',
24+
MY_TEAMS_PROJECTS: "My Team's Projects",
25+
PROJECTS_IM_LEADING: "Projects I'm Leading",
26+
2127
// Change Request
2228
CR_ROW: (title) => testIdBuilder(`${title}crRow`),
2329
NEW_CHANGE_REQUEST_BUTTON: 'New Change Request',

0 commit comments

Comments
 (0)