-
Notifications
You must be signed in to change notification settings - Fork 3
AB#31178 Add Cypress spec for email and update lists.cy.ts to make it select an intake before testing the dashboard. #1841
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AB#31178 Add Cypress spec for email and update lists.cy.ts to make it select an intake before testing the dashboard. #1841
Conversation
… select an intake before testing the dashboard.
|
Thanks for the quick turnaround on this testing/cypress work |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request adds a new Cypress email test specification and upgrades key dependencies in the Unity.AutoUI test automation project. The PR upgrades Cypress from version 13.13.1 to 14.5.4 (a major version bump) and TypeScript from 5.5.4 to 5.8.3, while also moving Cypress to devDependencies and adding experimental memory management configuration.
Key changes:
- Dependency Upgrades: Cypress upgraded to v14.5.4 (major version) and TypeScript to v5.8.3, with Cypress moved to devDependencies
- New Email Test: Comprehensive test suite for email functionality including template selection, recipient configuration, and email sending
- Memory Management: Added experimental memory management settings to Cypress configuration to optimize test performance
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| package.json | Upgraded TypeScript to ^5.8.3 and moved Cypress (^14.5.4) from dependencies to devDependencies |
| package-lock.json | Updated dependency tree reflecting Cypress 14.5.4 upgrade and all transitive dependency updates |
| basicEmail.cy.ts | New comprehensive Cypress test suite for email functionality with tenant switching, form filling, and email sending workflow |
| cypress.config.ts | Added experimentalMemoryManagement and numTestsKeptInMemory configuration options |
Files not reviewed (1)
- applications/Unity.AutoUI/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "dependencies": { | ||
| "cypress": "^13.13.1", | ||
| "typescript": "^5.5.4" | ||
| "typescript": "^5.8.3" |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The package.json specifies TypeScript version ^5.8.3, but the package-lock.json contains version 5.9.3. This version mismatch can lead to inconsistent behavior across different environments. The caret (^) allows minor and patch updates, which explains why 5.9.3 was installed, but it's important to either update package.json to match the actual version being used (5.9.3) or regenerate package-lock.json to use 5.8.3 if that's the intended version.
| "typescript": "^5.8.3" | |
| "typescript": "5.9.3" |
| "openMode": 0 | ||
| } | ||
| }, | ||
| }, |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a missing comma after the closing brace of the retries block. While JavaScript/TypeScript may be lenient in some cases, proper JSON-like syntax requires a comma between object properties. This should be corrected to ensure consistent formatting and avoid potential parsing issues.
| //it('Verify Login', () => { | ||
| // cy.login() | ||
| //}) | ||
|
|
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These commented-out lines appear to be leftover code. The test "Login" already exists at line 80-82, making this commented code redundant. Consider removing these commented lines to keep the codebase clean and avoid confusion.
| //it('Verify Login', () => { | |
| // cy.login() | |
| //}) |
| describe('Send an email', () => { | ||
| const TEST_EMAIL_TO = 'grantmanagementsupport@gov.bc.ca' | ||
| const TEST_EMAIL_CC = 'UnitySupport@gov.bc.ca' | ||
| const TEST_EMAIL_BCC = 'UNITYSUP@Victoria1.gov.bc.ca' | ||
| const TEMPLATE_NAME = 'Test Case 1' | ||
|
|
||
| const now = new Date() | ||
| const timestamp = | ||
| now.getFullYear() + | ||
| '-' + | ||
| String(now.getMonth() + 1).padStart(2, '0') + | ||
| '-' + | ||
| String(now.getDate()).padStart(2, '0') + | ||
| ' ' + | ||
| String(now.getHours()).padStart(2, '0') + | ||
| ':' + | ||
| String(now.getMinutes()).padStart(2, '0') + | ||
| ':' + | ||
| String(now.getSeconds()).padStart(2, '0') | ||
|
|
||
| const TEST_EMAIL_SUBJECT = `Smoke Test Email ${timestamp}` | ||
|
|
||
| //it('Verify Login', () => { | ||
| // cy.login() | ||
| //}) |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR description states "update lists.cy.ts to make it select an intake before testing the dashboard," but no changes to lists.cy.ts are visible in this diff. The lists.cy.ts file currently only verifies that the user is already on the "Default Grants Program" tenant (line 10) but doesn't actually switch to it. If the PR description is accurate, the changes to lists.cy.ts may be missing from this pull request.
| function switchToDefaultGrantsProgramIfAvailable() { | ||
| cy.get('body').then(($body) => { | ||
| // If we are already on GrantPrograms (or can navigate there), try. Otherwise skip quietly. | ||
| // Key point: never .should() an optional element. | ||
| const hasUserInitials = $body.find('.unity-user-initials').length > 0 | ||
|
|
||
| if (!hasUserInitials) { | ||
| cy.log('Skipping tenant switch: no user initials menu found') | ||
| return | ||
| } | ||
|
|
||
| cy.get('.unity-user-initials').click() | ||
|
|
||
| cy.get('body').then(($body2) => { | ||
| const switchLink = $body2.find('#user-dropdown a.dropdown-item').filter((_, el) => { | ||
| return (el.textContent || '').trim() === 'Switch Grant Programs' | ||
| }) | ||
|
|
||
| if (switchLink.length === 0) { | ||
| cy.log('Skipping tenant switch: "Switch Grant Programs" not present for this user/session') | ||
| // Close dropdown so it does not block clicks later | ||
| cy.get('body').click(0, 0) | ||
| return | ||
| } | ||
|
|
||
| cy.wrap(switchLink.first()).click() | ||
|
|
||
| cy.url({ timeout: 20000 }).should('include', '/GrantPrograms') | ||
|
|
||
| cy.get('#search-grant-programs', { timeout: 20000 }) | ||
| .should('be.visible') | ||
| .clear() | ||
| .type('Default Grants Program') | ||
|
|
||
| cy.get('#UserGrantProgramsTable', { timeout: 20000 }) | ||
| .should('be.visible') | ||
| .within(() => { | ||
| cy.contains('tbody tr', 'Default Grants Program', { timeout: 20000 }) | ||
| .should('exist') | ||
| .within(() => { | ||
| cy.contains('button', 'Select') | ||
| .should('be.enabled') | ||
| .click() | ||
| }) | ||
| }) | ||
|
|
||
| cy.location('pathname', { timeout: 20000 }).should((p) => { | ||
| expect(p.indexOf('/GrantApplications') >= 0 || p.indexOf('/auth/') >= 0).to.eq(true) | ||
| }) | ||
| }) | ||
| }) | ||
| } |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The switchToDefaultGrantsProgramIfAvailable function uses nested cy.get('body').then() callbacks which can make the test logic harder to follow and maintain. Consider refactoring this to use Cypress aliases or breaking it into smaller, more focused helper functions. This would improve readability and make the test easier to debug if issues arise.
| cy.url({ timeout: 20000 }).should('include', '/GrantPrograms') | ||
|
|
||
| cy.get('#search-grant-programs', { timeout: 20000 }) | ||
| .should('be.visible') | ||
| .clear() | ||
| .type('Default Grants Program') | ||
|
|
||
| cy.get('#UserGrantProgramsTable', { timeout: 20000 }) | ||
| .should('be.visible') | ||
| .within(() => { | ||
| cy.contains('tbody tr', 'Default Grants Program', { timeout: 20000 }) | ||
| .should('exist') | ||
| .within(() => { | ||
| cy.contains('button', 'Select') | ||
| .should('be.enabled') | ||
| .click() | ||
| }) | ||
| }) | ||
|
|
||
| cy.location('pathname', { timeout: 20000 }).should((p) => { | ||
| expect(p.indexOf('/GrantApplications') >= 0 || p.indexOf('/auth/') >= 0).to.eq(true) | ||
| }) | ||
| }) | ||
| }) | ||
| } | ||
|
|
||
| it('Login', () => { | ||
| cy.login() | ||
| }) | ||
|
|
||
| it('Switch to Default Grants Program if available', () => { | ||
| switchToDefaultGrantsProgramIfAvailable() | ||
| }) | ||
|
|
||
| it('Handle IDIR if required', () => { | ||
| cy.get('body').then(($body) => { | ||
| if ($body.find('#social-idir').length > 0) { | ||
| cy.get('#social-idir').should('be.visible').click() | ||
| } | ||
| }) | ||
|
|
||
| cy.location('pathname', { timeout: 30000 }).should('include', '/GrantApplications') | ||
| }) | ||
|
|
||
| it('Open an application from the list', () => { | ||
| cy.url().should('include', '/GrantApplications') | ||
|
|
||
| cy.get('#GrantApplicationsTable tbody a[href^="/GrantApplications/Details?ApplicationId="]', { timeout: 20000 }) | ||
| .should('have.length.greaterThan', 0) | ||
|
|
||
| cy.get('#GrantApplicationsTable tbody a[href^="/GrantApplications/Details?ApplicationId="]') | ||
| .first() | ||
| .click() | ||
|
|
||
| cy.url().should('include', '/GrantApplications/Details') | ||
| }) | ||
|
|
||
| it('Open Emails tab', () => { | ||
| cy.get('#emails-tab', { timeout: 20000 }) | ||
| .should('exist') | ||
| .should('be.visible') | ||
| .click() | ||
|
|
||
| cy.contains('Emails', { timeout: 20000 }).should('exist') | ||
| cy.contains('Email History', { timeout: 20000 }).should('exist') | ||
| }) | ||
|
|
||
| it('Open New Email form', () => { | ||
| cy.get('#btn-new-email', { timeout: 20000 }) | ||
| .should('exist') | ||
| .should('be.visible') | ||
| .click() | ||
|
|
||
| cy.contains('Email To', { timeout: 20000 }).should('exist') | ||
| }) | ||
|
|
||
| it('Select Email Template', () => { | ||
| cy.intercept('GET', '/api/app/template/*/template-by-id').as('loadTemplate') | ||
|
|
||
| cy.get('#template', { timeout: 20000 }) | ||
| .should('exist') | ||
| .should('be.visible') | ||
| .select(TEMPLATE_NAME) | ||
|
|
||
| cy.wait('@loadTemplate', { timeout: 20000 }) | ||
|
|
||
| cy.get('#template') | ||
| .find('option:selected') | ||
| .should('have.text', TEMPLATE_NAME) | ||
| }) | ||
|
|
||
| it('Set Email To address', () => { | ||
| cy.get('#EmailTo', { timeout: 20000 }) | ||
| .should('exist') | ||
| .should('be.visible') | ||
| .clear() | ||
| .type(TEST_EMAIL_TO) | ||
|
|
||
| cy.get('#EmailTo').should('have.value', TEST_EMAIL_TO) | ||
| }) | ||
|
|
||
| it('Set Email CC address', () => { | ||
| cy.get('#EmailCC', { timeout: 20000 }) | ||
| .should('exist') | ||
| .should('be.visible') | ||
| .clear() | ||
| .type(TEST_EMAIL_CC) | ||
|
|
||
| cy.get('#EmailCC').should('have.value', TEST_EMAIL_CC) | ||
| }) | ||
|
|
||
| it('Set Email BCC address', () => { | ||
| cy.get('#EmailBCC', { timeout: 20000 }) | ||
| .should('exist') | ||
| .should('be.visible') | ||
| .clear() | ||
| .type(TEST_EMAIL_BCC) | ||
|
|
||
| cy.get('#EmailBCC').should('have.value', TEST_EMAIL_BCC) | ||
| }) | ||
|
|
||
| it('Set Email Subject', () => { | ||
| cy.get('#EmailSubject', { timeout: 20000 }) | ||
| .should('exist') | ||
| .should('be.visible') | ||
| .clear() | ||
| .type(TEST_EMAIL_SUBJECT) | ||
|
|
||
| cy.get('#EmailSubject').should('have.value', TEST_EMAIL_SUBJECT) | ||
| }) | ||
|
|
||
| it('Save the email', () => { | ||
| cy.get('#btn-save', { timeout: 20000 }) | ||
| .should('exist') | ||
| .should('be.visible') | ||
| .click() | ||
|
|
||
| cy.get('#btn-new-email', { timeout: 20000 }).should('be.visible') | ||
| }) | ||
|
|
||
| it('Select saved email from Email History', () => { | ||
| cy.contains('td.data-table-header', TEST_EMAIL_SUBJECT, { timeout: 20000 }) | ||
| .should('exist') | ||
| .click() | ||
|
|
||
| cy.get('#EmailTo', { timeout: 20000 }).should('be.visible') | ||
| cy.get('#EmailCC').should('be.visible') | ||
| cy.get('#EmailBCC').should('be.visible') | ||
| cy.get('#EmailSubject').should('be.visible') | ||
|
|
||
| cy.get('#btn-send').should('be.visible') | ||
| cy.get('#btn-save').should('be.visible') | ||
| }) | ||
|
|
||
| it('Send the email', () => { | ||
| cy.get('#btn-send', { timeout: 20000 }) | ||
| .should('exist') | ||
| .should('be.visible') | ||
| .click() | ||
| }) | ||
|
|
||
| it('Confirm send email in modal', () => { | ||
| cy.get('#modal-content', { timeout: 20000 }) | ||
| .should('exist') | ||
| .should('be.visible') | ||
|
|
||
| cy.contains('Are you sure you want to send this email?', { timeout: 20000 }) | ||
| .should('exist') | ||
|
|
||
| cy.get('#btn-confirm-send', { timeout: 20000 }) | ||
| .should('exist') | ||
| .should('be.visible') | ||
| .click() | ||
| }) |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test uses hardcoded timeout values of 20000ms in multiple places, which could benefit from being extracted to a constant at the top of the file or using Cypress's defaultCommandTimeout configuration. This would make timeout adjustments easier and more consistent across all test steps.
…ists.cy.ts and adds a refactored basicEmail.cy.ts to generate a single email as part of the smoke test.
AB#31178 Add Cypress spec for email and update lists.cy.ts to make it select an intake before testing the dashboard.