Skip to content

Commit d43f371

Browse files
committed
test: address Cypress PR feedback
1 parent 95f346e commit d43f371

14 files changed

Lines changed: 177 additions & 739 deletions

CYPRESS_PLAN.md

Lines changed: 0 additions & 307 deletions
This file was deleted.

cypress/e2e/docker/pushActions.cy.js

Lines changed: 2 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ describe('Push Actions (Approve, Reject, Cancel)', () => {
3030
};
3131

3232
before(() => {
33-
// Setup: login as admin, create test users, assign permissions
3433
cy.login('admin', 'admin');
3534

3635
cy.createUser(testUser.username, testUser.password, testUser.email, testUser.gitAccount);
@@ -50,15 +49,13 @@ describe('Push Actions (Approve, Reject, Cancel)', () => {
5049
});
5150

5251
afterEach(function () {
53-
// Clean up push created in this test (if any)
5452
if (this.pushId) {
5553
cy.deleteTestPush(this.pushId);
5654
}
5755
cy.logout();
5856
});
5957

6058
after(() => {
61-
// Clean up test users
6259
cy.deleteTestUser(testUser.username);
6360
cy.deleteTestUser(approverUser.username);
6461
});
@@ -73,43 +70,32 @@ describe('Push Actions (Approve, Reject, Cancel)', () => {
7370
cy.login(approverUser.username, approverUser.password);
7471
cy.visit(`/dashboard/push/${this.pushId}`);
7572

76-
// Verify push is Pending
7773
cy.get('[data-testid="push-status"]').should('contain', 'Pending');
7874

79-
// Action buttons should be visible
8075
cy.get('[data-testid="push-cancel-btn"]').should('be.visible');
8176
cy.get('[data-testid="push-reject-btn"]').should('be.visible');
8277
cy.get('[data-testid="attestation-open-btn"]').should('be.visible');
8378

84-
// Open attestation dialog
8579
cy.get('[data-testid="attestation-open-btn"]').click();
8680
cy.get('[data-testid="attestation-dialog"]').should('be.visible');
8781

88-
// Confirm button should be disabled until all checkboxes are checked
8982
cy.get('[data-testid="attestation-confirm-btn"]').should('be.disabled');
9083

91-
// Check all attestation checkboxes
9284
cy.get('[data-testid="attestation-dialog"]')
9385
.find('input[type="checkbox"]')
9486
.each(($checkbox) => {
9587
cy.wrap($checkbox).check({ force: true });
9688
});
9789

98-
// Confirm button should now be enabled
9990
cy.get('[data-testid="attestation-confirm-btn"]').should('not.be.disabled');
100-
101-
// Click confirm to approve
10291
cy.get('[data-testid="attestation-confirm-btn"]').click();
10392

104-
// Should navigate back to push list
10593
cy.url().should('include', '/dashboard/push');
10694
cy.url().should('not.include', this.pushId);
10795

108-
// Verify push is now Approved by revisiting its detail page
10996
cy.visit(`/dashboard/push/${this.pushId}`);
11097
cy.get('[data-testid="push-status"]').should('contain', 'Approved');
11198

112-
// Action buttons should no longer be visible for an approved push
11399
cy.get('[data-testid="push-cancel-btn"]').should('not.exist');
114100
cy.get('[data-testid="push-reject-btn"]').should('not.exist');
115101
cy.get('[data-testid="attestation-open-btn"]').should('not.exist');
@@ -126,33 +112,22 @@ describe('Push Actions (Approve, Reject, Cancel)', () => {
126112
cy.login(approverUser.username, approverUser.password);
127113
cy.visit(`/dashboard/push/${this.pushId}`);
128114

129-
// Verify push is Pending
130115
cy.get('[data-testid="push-status"]').should('contain', 'Pending');
131116

132-
// Open reject dialog
133117
cy.get('[data-testid="push-reject-btn"]').click();
134118

135-
// Confirm button should be disabled until reason is provided
136119
cy.get('[data-testid="push-reject-confirm-btn"]').should('be.disabled');
137-
138-
// Fill in rejection reason
139120
cy.get('#reason').type('Rejecting for test purposes');
140121

141-
// Confirm button should now be enabled
142122
cy.get('[data-testid="push-reject-confirm-btn"]').should('not.be.disabled');
143-
144-
// Confirm rejection
145123
cy.get('[data-testid="push-reject-confirm-btn"]').click();
146124

147-
// Should navigate back to push list
148125
cy.url().should('include', '/dashboard/push');
149126
cy.url().should('not.include', this.pushId);
150127

151-
// Verify push is now Rejected
152128
cy.visit(`/dashboard/push/${this.pushId}`);
153129
cy.get('[data-testid="push-status"]').should('contain', 'Rejected');
154130

155-
// Action buttons should no longer be visible
156131
cy.get('[data-testid="push-cancel-btn"]').should('not.exist');
157132
cy.get('[data-testid="push-reject-btn"]').should('not.exist');
158133
cy.get('[data-testid="attestation-open-btn"]').should('not.exist');
@@ -166,24 +141,17 @@ describe('Push Actions (Approve, Reject, Cancel)', () => {
166141
});
167142

168143
it('should cancel a pending push', function () {
169-
// Cancel can be done by the push author
170144
cy.login(testUser.username, testUser.password);
171145
cy.visit(`/dashboard/push/${this.pushId}`);
172146

173-
// Verify push is Pending
174147
cy.get('[data-testid="push-status"]').should('contain', 'Pending');
175-
176-
// Click Cancel
177148
cy.get('[data-testid="push-cancel-btn"]').click();
178149

179-
// Should navigate back to push list
180150
cy.url().should('include', '/dashboard/push');
181151

182-
// Verify push is now Canceled
183152
cy.visit(`/dashboard/push/${this.pushId}`);
184153
cy.get('[data-testid="push-status"]').should('contain', 'Canceled');
185154

186-
// Action buttons should no longer be visible
187155
cy.get('[data-testid="push-cancel-btn"]').should('not.exist');
188156
cy.get('[data-testid="push-reject-btn"]').should('not.exist');
189157
cy.get('[data-testid="attestation-open-btn"]').should('not.exist');
@@ -192,25 +160,19 @@ describe('Push Actions (Approve, Reject, Cancel)', () => {
192160

193161
describe('Negative: unauthorized approve', () => {
194162
beforeEach(() => {
195-
// Rate-limit guard: wait to avoid 429 from rapid push creations
196-
// eslint-disable-next-line cypress/no-unnecessary-waiting
197-
cy.wait(2000);
198163
const suffix = `neg-approve-${Date.now()}`;
199164
cy.createPush(testUser.username, testUser.password, testUser.email, suffix).as('pushId');
200165
});
201166

202167
it('should not change push state when user lacks canAuthorise permission', function () {
203-
// Login as testuser (has canPush but NOT canAuthorise)
204168
cy.login(testUser.username, testUser.password);
205169
cy.visit(`/dashboard/push/${this.pushId}`);
206170

207171
cy.get('[data-testid="push-status"]').should('contain', 'Pending');
208172

209-
// Open attestation dialog and attempt to approve
210173
cy.get('[data-testid="attestation-open-btn"]').click();
211174
cy.get('[data-testid="attestation-dialog"]').should('be.visible');
212175

213-
// Check all checkboxes
214176
cy.get('[data-testid="attestation-dialog"]')
215177
.find('input[type="checkbox"]')
216178
.each(($checkbox) => {
@@ -219,46 +181,33 @@ describe('Push Actions (Approve, Reject, Cancel)', () => {
219181

220182
cy.get('[data-testid="attestation-confirm-btn"]').click();
221183

222-
// TODO: The server correctly returns 403 but the UI (src/ui/services/git-push.ts)
223-
// only handles 401 errors in authorisePush/rejectPush. The 403 is silently
224-
// ignored and the user is navigated away without feedback. Once the UI properly
225-
// handles 403, this test should assert a snackbar error message is shown.
184+
// TODO: Assert snackbar feedback when the UI handles 403 push action responses.
226185
cy.visit(`/dashboard/push/${this.pushId}`);
227186
cy.get('[data-testid="push-status"]').should('contain', 'Pending');
228187
});
229188
});
230189

231190
describe('Negative: unauthorized reject', () => {
232191
beforeEach(() => {
233-
// Rate-limit guard: wait to avoid 429 from rapid push creations
234-
// eslint-disable-next-line cypress/no-unnecessary-waiting
235-
cy.wait(2000);
236192
const suffix = `neg-reject-${Date.now()}`;
237193
cy.createPush(testUser.username, testUser.password, testUser.email, suffix).as('pushId');
238194
});
239195

240196
it('should not change push state when user lacks canAuthorise permission', function () {
241-
// Login as testuser
242197
cy.login(testUser.username, testUser.password);
243198
cy.visit(`/dashboard/push/${this.pushId}`);
244199

245200
cy.get('[data-testid="push-status"]').should('contain', 'Pending');
246-
247-
// Click Reject
248201
cy.get('[data-testid="push-reject-btn"]').click();
249202

250-
// TODO: Same issue as unauthorized approve — UI ignores 403 from server.
251-
// Once fixed, assert snackbar error message is shown.
203+
// TODO: Assert snackbar feedback when the UI handles 403 push action responses.
252204
cy.visit(`/dashboard/push/${this.pushId}`);
253205
cy.get('[data-testid="push-status"]').should('contain', 'Pending');
254206
});
255207
});
256208

257209
describe('Attestation dialog cancel does not cancel the push', () => {
258210
beforeEach(() => {
259-
// Rate-limit guard: wait to avoid 429 from rapid push creations
260-
// eslint-disable-next-line cypress/no-unnecessary-waiting
261-
cy.wait(2000);
262211
const suffix = `dialog-cancel-${Date.now()}`;
263212
cy.createPush(testUser.username, testUser.password, testUser.email, suffix).as('pushId');
264213
});
@@ -269,18 +218,14 @@ describe('Push Actions (Approve, Reject, Cancel)', () => {
269218

270219
cy.get('[data-testid="push-status"]').should('contain', 'Pending');
271220

272-
// Open attestation dialog
273221
cy.get('[data-testid="attestation-open-btn"]').click();
274222
cy.get('[data-testid="attestation-dialog"]').should('be.visible');
275223

276-
// Click the dialog's Cancel button (NOT the push cancel button)
277224
cy.get('[data-testid="attestation-cancel-btn"]').click();
278225

279-
// Dialog should close, push should still be pending
280226
cy.get('[data-testid="attestation-dialog"]').should('not.exist');
281227
cy.get('[data-testid="push-status"]').should('contain', 'Pending');
282228

283-
// Action buttons should still be visible (push is still pending)
284229
cy.get('[data-testid="push-cancel-btn"]').should('be.visible');
285230
cy.get('[data-testid="push-reject-btn"]').should('be.visible');
286231
cy.get('[data-testid="attestation-open-btn"]').should('be.visible');

cypress/e2e/error-pages.cy.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,13 @@ describe('Error Pages', () => {
2626
afterEach(() => {
2727
cy.logout();
2828
});
29-
30-
// --- 9.1 Unknown route shows 404 ---
31-
it('9.1 — Unknown route shows 404 page', () => {
29+
it('Unknown route shows 404 page', () => {
3230
cy.visit('/dashboard/nonexistent-page-xyz');
3331

3432
cy.get('[data-testid="not-found-page"]').should('be.visible');
3533
cy.contains('404').should('be.visible');
3634
});
37-
38-
// --- 9.2 Unauthorized route shows NotAuthorized ---
39-
it('9.2 — Unauthorized route shows NotAuthorized page', () => {
40-
// Create a non-admin user and try to access admin route
35+
it('Unauthorized route shows NotAuthorized page', () => {
4136
const regularUser = {
4237
username: `errorpage_user_${Date.now()}`,
4338
password: 'pass123',
@@ -55,14 +50,10 @@ describe('Error Pages', () => {
5550
cy.clearCookies();
5651
cy.clearLocalStorage();
5752
cy.login(regularUser.username, regularUser.password);
58-
59-
// Navigate to not-authorized page directly to verify it renders
6053
cy.visit('/not-authorized');
6154

6255
cy.get('[data-testid="not-authorized-page"]').should('be.visible');
6356
cy.contains('403').should('be.visible');
64-
65-
// Clean up user
6657
cy.clearCookies();
6758
cy.deleteTestUser(regularUser.username);
6859
});

cypress/e2e/navigation.cy.js

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,72 +26,44 @@ describe('Navigation & Shell', () => {
2626
afterEach(() => {
2727
cy.logout();
2828
});
29-
30-
// --- 8.1 Sidebar renders all visible links ---
31-
it('8.1 — Sidebar renders all visible links', () => {
29+
it('Sidebar renders all visible links', () => {
3230
cy.visit('/dashboard/repo');
33-
34-
// Sidebar links should be present
3531
cy.contains('Repositories').should('be.visible');
3632
cy.contains('Dashboard').should('be.visible');
3733
});
38-
39-
// --- 8.2 Sidebar links navigate correctly ---
40-
it('8.2 — Sidebar links navigate correctly', () => {
34+
it('Sidebar links navigate correctly', () => {
4135
cy.visit('/dashboard/repo');
42-
43-
// Navigate to push dashboard
4436
cy.contains('Dashboard').click();
4537
cy.url().should('include', '/dashboard/push');
46-
47-
// Navigate back to repos
4838
cy.contains('Repositories').click();
4939
cy.url().should('include', '/dashboard/repo');
5040
});
51-
52-
// --- 8.3 Active sidebar item highlights ---
53-
it('8.3 — Active sidebar item highlights', () => {
41+
it('Active sidebar item highlights', () => {
5442
cy.visit('/dashboard/repo');
55-
56-
// The active nav link should have aria-current="page"
5743
cy.get('[aria-current="page"]').should('exist');
5844
});
59-
60-
// --- 8.4 Navbar renders ---
61-
it('8.4 — Navbar renders correctly', () => {
45+
it('Navbar renders correctly', () => {
6246
cy.visit('/dashboard/repo');
6347

6448
cy.get('[data-testid="navbar"]').should('be.visible');
6549
});
66-
67-
// --- 8.5 Footer renders ---
68-
it('8.5 — Footer renders', () => {
50+
it('Footer renders', () => {
6951
cy.visit('/dashboard/repo');
7052

7153
cy.get('[data-testid="footer"]').should('exist');
7254
cy.get('[data-testid="footer"]').scrollIntoView();
7355
cy.get('[data-testid="footer"]').should('be.visible');
7456
});
75-
76-
// --- 8.6 Unauthenticated user redirected ---
77-
// NOTE: This test must run WITHOUT a login session, otherwise cy.session()
78-
// caches authenticated cookies and restores them on cy.visit() despite
79-
// cy.clearCookies() / cy.clearLocalStorage(). We place it in its own
80-
// describe block that has no beforeEach login hook.
81-
82-
// --- 8.7 Root redirects to dashboard/repo ---
83-
it('8.7 — / redirects to /dashboard/repo', () => {
57+
// NOTE: Keep unauthenticated checks outside the logged-in hooks.
58+
it('/ redirects to /dashboard/repo', () => {
8459
cy.logout();
8560
cy.visit('/');
86-
87-
// Root should redirect (either to login if not authenticated, or to dashboard/repo)
8861
cy.url().should('match', /\/(login|dashboard)/);
8962
});
9063
});
9164

9265
describe('Unauthenticated access', () => {
93-
it('8.6 — Unauthenticated user is redirected to /login', () => {
94-
// Clear any saved Cypress sessions so no auth cookies are restored
66+
it('Unauthenticated user is redirected to /login', () => {
9567
Cypress.session.clearAllSavedSessions();
9668
cy.clearCookies();
9769
cy.clearLocalStorage();

0 commit comments

Comments
 (0)