From 225d69699e37d9dcf6076b180cd8f341f02e6926 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Mon, 22 Jul 2024 09:22:22 -0300 Subject: [PATCH 01/38] fix: simplify email address names to avoid issues with IMAP --- tests_cypress/cypress/Notify/NotifyAPI.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests_cypress/cypress/Notify/NotifyAPI.js b/tests_cypress/cypress/Notify/NotifyAPI.js index 4db444bb00..45da8ac91f 100644 --- a/tests_cypress/cypress/Notify/NotifyAPI.js +++ b/tests_cypress/cypress/Notify/NotifyAPI.js @@ -15,7 +15,7 @@ const Utilities = { return jwt.jws.JWS.sign("HS256", JSON.stringify(headers), JSON.stringify(claims), Cypress.env('ADMIN_SECRET')); }, GenerateID: (length = 10) => { - const nanoid = customAlphabet('1234567890abcdef-_', length) + const nanoid = customAlphabet('1234567890abcdef', length) return nanoid() } }; @@ -75,6 +75,22 @@ const Admin = { } }) }, + CreateUITestUser: () => { + var token = Utilities.CreateJWT(); + // generate random 10 char string + var username = Utilities.GenerateID(10); + return cy.request({ + failOnStatusCode: false, + url: `${BASE_URL}/cypress/create_user/${username}`, + method: 'GET', + // headers: { + // Authorization: `Bearer ${token}`, + // "Content-Type": 'application/json' + // }, + }).then((resp) => { + cy.wrap(resp.body.email_address).as('username'); + }); + }, } // const Admin = { // CreateService: () => { From c3eb799e3b4f9923b0271e52fdae498c2c5a232e Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Mon, 22 Jul 2024 09:23:04 -0300 Subject: [PATCH 02/38] fix: modify Login method to accept email alias to check for when connecting to IMAP --- tests_cypress/cypress/Notify/Admin/Pages/LoginPage.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests_cypress/cypress/Notify/Admin/Pages/LoginPage.js b/tests_cypress/cypress/Notify/Admin/Pages/LoginPage.js index 448b07f562..60ab0c1604 100644 --- a/tests_cypress/cypress/Notify/Admin/Pages/LoginPage.js +++ b/tests_cypress/cypress/Notify/Admin/Pages/LoginPage.js @@ -19,7 +19,7 @@ let Actions = { }, Login: (email, password, agreeToTerms=true) => { cy.clearCookie(ADMIN_COOKIE); // clear auth cookie - cy.task('deleteAllEmails'); // purge email inbox to make getting the 2fa code easier + // cy.task('deleteAllEmails'); // purge email inbox to make getting the 2fa code easier // login with username and password cy.visit(LoginPage.URL); @@ -29,7 +29,7 @@ let Actions = { // get email 2fa code recurse( - () => cy.task('getLastEmail', {} ), // Cypress commands to retry + () => cy.task('getLastEmail', email), // Cypress commands to retry Cypress._.isObject, // keep retrying until the task returns an object { log: true, From be37e0b57934771fd97120321b8b887a327bd181 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Mon, 22 Jul 2024 09:23:32 -0300 Subject: [PATCH 03/38] fix: new accounts go to /services page since they only belong to one service --- tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js b/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js index aa80431386..1d768b42de 100644 --- a/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js +++ b/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js @@ -12,7 +12,7 @@ let Actions = { AgreeToTerms: () => { TouPrompt.Components.Terms().scrollTo('bottom', { ensureScrollable: false }); Components.DismissButton().click(); - cy.url().should('include', '/accounts'); + cy.url().should('include', '/services'); }, }; From 7971d88672f13894c0b1b3b9bfc4d0dc6341f561 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Mon, 22 Jul 2024 09:29:57 -0300 Subject: [PATCH 04/38] feat: new plugin to generate a random email alias, then call an endpoint on the API to create a UI testing account with it --- .../cypress/plugins/create-account.js | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 tests_cypress/cypress/plugins/create-account.js diff --git a/tests_cypress/cypress/plugins/create-account.js b/tests_cypress/cypress/plugins/create-account.js new file mode 100644 index 0000000000..771017cb77 --- /dev/null +++ b/tests_cypress/cypress/plugins/create-account.js @@ -0,0 +1,72 @@ +const http = require('http'); +const https = require('https'); + +// TODO: This duplicates some code in Notify/NotifyAPI.js and should be consolidated +const Utilities = { + CreateJWT: (username, secret) => { + const jwt = require('jsrsasign'); + const claims = { + 'iss': username, + 'iat': Math.round(Date.now() / 1000) + } + + const headers = { alg: "HS256", typ: "JWT" }; + return jwt.jws.JWS.sign("HS256", JSON.stringify(headers), JSON.stringify(claims), secret); + }, + GenerateID: (length = 10) => { + const characters = '0123456789abcdefghijklmnopqrstuvwxyz'; + let result = ''; + const charactersLength = characters.length; + for (let i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; + } +}; + +const createAccount = async (baseUrl, username, secret) => { + // return a generated id + const token = Utilities.CreateJWT(username, secret); + const generatedUsername = Utilities.GenerateID(10); + const url = `${baseUrl}/cypress/create_user/${generatedUsername}`; + console.log('generatedUsername', generatedUsername); + + return new Promise((resolve, reject) => { + const options = { + method: 'GET', // or 'POST', depending on your API + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": 'application/json' + } + }; + + const getHttpModule = (url) => url.startsWith('https://') ? https : http; + + const req = getHttpModule(url).request(url, options, (res) => { + let data = ''; + + res.on('data', (chunk) => { + data += chunk; + }); + + res.on('end', () => { + try { + const parsedData = JSON.parse(data); + resolve(parsedData); + } catch (e) { + reject(e); + } + }); + }); + + req.on('error', (error) => { + reject(error); // Reject the promise on request error + }); + + req.end(); + }); + +}; + + +module.exports = createAccount; From 2f4ade73efc55df64528c6f2bc0fbae981b7e4a9 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Mon, 22 Jul 2024 09:30:44 -0300 Subject: [PATCH 05/38] fix: update cypress config to expose the create-account plugin, and store the email address while cypress is running --- tests_cypress/cypress.config.js | 19 +++++- .../cypress/plugins/email-account.js | 58 ++++++++++++------- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/tests_cypress/cypress.config.js b/tests_cypress/cypress.config.js index fd79f394ca..f77225abb2 100644 --- a/tests_cypress/cypress.config.js +++ b/tests_cypress/cypress.config.js @@ -1,7 +1,8 @@ var config = require('./config'); const { defineConfig } = require("cypress"); -const EmailAccount = require("./cypress/plugins/email-account") +const EmailAccount = require("./cypress/plugins/email-account"); +const CreateAccount = require("./cypress/plugins/create-account"); const htmlvalidate = require("cypress-html-validate/plugin"); module.exports = defineConfig({ @@ -28,8 +29,8 @@ module.exports = defineConfig({ return null }, // Email Account /// - getLastEmail() { - return emailAccount.getLastEmail() + getLastEmail(emailAddress) { + return emailAccount.getLastEmail(emailAddress) }, deleteAllEmails() { return emailAccount.deleteAllEmails() @@ -40,6 +41,18 @@ module.exports = defineConfig({ createEmailAccount() { return emailAccount.createEmailAccount(); }, + createAccount({ baseUrl, username, secret }) { + if (global.acct) { + return global.acct; + } else { + let acct = CreateAccount(baseUrl, username, secret); + global.acct = acct; + return acct + } + }, + getUserName() { + return global.stuff; + } }); on('before:browser:launch', (browser = {}, launchOptions) => { diff --git a/tests_cypress/cypress/plugins/email-account.js b/tests_cypress/cypress/plugins/email-account.js index 93b3ad9f67..2d52205cba 100644 --- a/tests_cypress/cypress/plugins/email-account.js +++ b/tests_cypress/cypress/plugins/email-account.js @@ -75,42 +75,58 @@ const emailAccount = async () => { * Utility method for getting the last email * for the Ethereal email account */ - async getLastEmail() { + async getLastEmail(emailAddress) { // makes debugging very simple - // console.log('Getting the last email') + console.log('Getting the last email', emailAddress) try { const connection = await imaps.connect(emailConfig) // grab up to 50 emails from the inbox await connection.openBox('INBOX') - const searchCriteria = ['1:50', 'UNDELETED'] + const searchCriteria = ['UNSEEN']; const fetchOptions = { bodies: [''], - } + struct: true, + }; const messages = await connection.search(searchCriteria, fetchOptions) - // and close the connection to avoid it hanging - connection.end() - + // connection.end(); if (!messages.length) { - // console.log('Cannot find any emails') + console.log('Cannot find any emails') return null } else { - // console.log('There are %d messages', messages.length) - // grab the last email - const mail = await simpleParser( - messages[messages.length - 1].parts[0].body, - ) - // console.log(mail.subject) - // console.log(mail.text) + let latestMail = null; + let uidsToDelete = []; + for (const message of messages) { + + const mail = await simpleParser(message.parts[0].body); + const to_address = mail.to.value[0].address; + console.log('to_address', to_address) + console.log('email', emailAddress); + console.log('---') + if (to_address == emailAddress) { + console.log('mafch found') + uidsToDelete.push(message.attributes.uid); + latestMail = { + subject: mail.subject, + text: mail.text, + html: mail.html, + } + } + } + + console.log('deleting', uidsToDelete); + try { + await connection.deleteMessage(uidsToDelete); + await connection.imap.expunge(); + } + catch (e) { + console.error('delete error', e) + } + connection.end() - // and returns the main fields - return { - subject: mail.subject, - text: mail.text, - html: mail.html, - } + return latestMail; } } catch (e) { // and close the connection to avoid it hanging From 7dc450d6e7ec98ed68c46c7429a3cd11ecacc817 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Mon, 22 Jul 2024 09:31:45 -0300 Subject: [PATCH 06/38] feat: update the login command to get the ephemeral email account before logging in --- tests_cypress/cypress/support/commands.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests_cypress/cypress/support/commands.js b/tests_cypress/cypress/support/commands.js index 6c4dcec387..ad209ffc9c 100644 --- a/tests_cypress/cypress/support/commands.js +++ b/tests_cypress/cypress/support/commands.js @@ -3,6 +3,7 @@ import "cypress-real-events"; import config from "../../config"; import LoginPage from "../Notify/Admin/Pages/LoginPage"; +import { Admin } from "../Notify/NotifyAPI"; // keep track of what we test so we dont test the same thing twice let links_checked = []; @@ -97,8 +98,10 @@ Cypress.Commands.add('getByTestId', (selector, ...args) => { return cy.get(`[data-testid=${selector}]`, ...args) }); -Cypress.Commands.add('login', (username, password, agreeToTerms = true) => { - cy.session([username, password, agreeToTerms], () => { - LoginPage.Login(username, password, agreeToTerms); +Cypress.Commands.add('login', (un, password, agreeToTerms = true) => { + cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET') }).then((acct) => { + cy.session([acct.email_address, password, agreeToTerms], () => { + LoginPage.Login(acct.email_address, password, agreeToTerms); + }); }); }); From 706be29121ac133d0b999ba509a7af6f326ef27b Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 13 Sep 2024 15:12:03 -0300 Subject: [PATCH 07/38] feat(create-account): update create account task and pass notify test user pw --- tests_cypress/cypress.config.js | 11 ++++----- .../cypress/plugins/create-account.js | 23 ++++++++++++------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/tests_cypress/cypress.config.js b/tests_cypress/cypress.config.js index f77225abb2..667004ff06 100644 --- a/tests_cypress/cypress.config.js +++ b/tests_cypress/cypress.config.js @@ -38,20 +38,17 @@ module.exports = defineConfig({ fetchEmail(acct) { return emailAccount.fetchEmail(acct) }, - createEmailAccount() { - return emailAccount.createEmailAccount(); - }, - createAccount({ baseUrl, username, secret }) { + createAccount({ baseUrl, username, secret, pw }) { if (global.acct) { return global.acct; } else { - let acct = CreateAccount(baseUrl, username, secret); + let acct = CreateAccount(baseUrl, username, secret, pw); global.acct = acct; return acct } }, getUserName() { - return global.stuff; + return global.acct; } }); @@ -68,6 +65,6 @@ module.exports = defineConfig({ viewportWidth: 1280, viewportHeight: 850, testIsolation: true, - retries: 3 + // retries: 3 }, }); diff --git a/tests_cypress/cypress/plugins/create-account.js b/tests_cypress/cypress/plugins/create-account.js index 771017cb77..fe79a35de7 100644 --- a/tests_cypress/cypress/plugins/create-account.js +++ b/tests_cypress/cypress/plugins/create-account.js @@ -24,31 +24,37 @@ const Utilities = { } }; -const createAccount = async (baseUrl, username, secret) => { +const createAccount = async (baseUrl, username, secret, pw) => { // return a generated id const token = Utilities.CreateJWT(username, secret); const generatedUsername = Utilities.GenerateID(10); const url = `${baseUrl}/cypress/create_user/${generatedUsername}`; - console.log('generatedUsername', generatedUsername); return new Promise((resolve, reject) => { + const postData = JSON.stringify({ + password: pw + }); + const options = { - method: 'GET', // or 'POST', depending on your API + method: 'POST', headers: { Authorization: `Bearer ${token}`, - "Content-Type": 'application/json' - } + "Content-Type": 'application/json', + 'Content-Length': Buffer.byteLength(postData) + }, }; - + const getHttpModule = (url) => url.startsWith('https://') ? https : http; const req = getHttpModule(url).request(url, options, (res) => { let data = ''; + // A chunk of data has been received. res.on('data', (chunk) => { data += chunk; }); + // The whole response has been received. res.on('end', () => { try { const parsedData = JSON.parse(data); @@ -62,10 +68,11 @@ const createAccount = async (baseUrl, username, secret) => { req.on('error', (error) => { reject(error); // Reject the promise on request error }); - + + // Write the POST parameters to the request body + req.write(postData); req.end(); }); - }; From d7e7f81a7ac7848630c9ae3a1751aca4c707fd3d Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 13 Sep 2024 15:12:42 -0300 Subject: [PATCH 08/38] fix(tou_test): success can either be the /accounts page or a /services/ page --- tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js b/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js index 1d768b42de..ee9e0d1791 100644 --- a/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js +++ b/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js @@ -12,7 +12,9 @@ let Actions = { AgreeToTerms: () => { TouPrompt.Components.Terms().scrollTo('bottom', { ensureScrollable: false }); Components.DismissButton().click(); - cy.url().should('include', '/services'); + // depending on how many services a user has, the app either goes to the /accounts page + // or to a specific service page - either means success + cy.url().should('match', /\/(accounts|services)/); }, }; From db9a550665083e11f057cec583b291505a721e89 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 13 Sep 2024 15:13:14 -0300 Subject: [PATCH 09/38] chore(email-account): refactor and clean up code a bit; ensure connections are always closed and not dangling --- .../cypress/plugins/email-account.js | 63 ++++++++----------- tests_cypress/cypress/support/commands.js | 2 +- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/tests_cypress/cypress/plugins/email-account.js b/tests_cypress/cypress/plugins/email-account.js index 2d52205cba..3fc7d24f05 100644 --- a/tests_cypress/cypress/plugins/email-account.js +++ b/tests_cypress/cypress/plugins/email-account.js @@ -75,65 +75,57 @@ const emailAccount = async () => { * Utility method for getting the last email * for the Ethereal email account */ - async getLastEmail(emailAddress) { - // makes debugging very simple - console.log('Getting the last email', emailAddress) - + async getLastEmail(emailAddress) { + let connection; try { - const connection = await imaps.connect(emailConfig) - + connection = await imaps.connect(emailConfig); + // grab up to 50 emails from the inbox - await connection.openBox('INBOX') + await connection.openBox('INBOX'); const searchCriteria = ['UNSEEN']; const fetchOptions = { bodies: [''], struct: true, }; - const messages = await connection.search(searchCriteria, fetchOptions) - // connection.end(); + const messages = await connection.search(searchCriteria, fetchOptions); + if (!messages.length) { - console.log('Cannot find any emails') - return null + console.log('Cannot find any emails'); + return null; } else { let latestMail = null; - let uidsToDelete = []; + let uidsToDelete = []; for (const message of messages) { - const mail = await simpleParser(message.parts[0].body); const to_address = mail.to.value[0].address; - console.log('to_address', to_address) - console.log('email', emailAddress); - console.log('---') - if (to_address == emailAddress) { - console.log('mafch found') - uidsToDelete.push(message.attributes.uid); + + if (to_address == emailAddress) { + uidsToDelete.push(message.attributes.uid); latestMail = { subject: mail.subject, text: mail.text, html: mail.html, - } + }; } } - + console.log('deleting', uidsToDelete); try { await connection.deleteMessage(uidsToDelete); await connection.imap.expunge(); + } catch (e) { + console.error('delete error', e); } - catch (e) { - console.error('delete error', e) - } - - connection.end() - - return latestMail; + + return latestMail; } } catch (e) { - // and close the connection to avoid it hanging - // connection.end() - - console.error(e) - return null + console.error(e); + return null; + } finally { + if (connection) { + connection.end(); + } } }, async fetchEmail(acct) { @@ -201,11 +193,6 @@ const emailAccount = async () => { console.error(e) return null } - }, - async createEmailAccount() { - let testAccount = await nodemailer.createTestAccount(); - // console.log("test account created: ", testAccount); - return testAccount; } } diff --git a/tests_cypress/cypress/support/commands.js b/tests_cypress/cypress/support/commands.js index ad209ffc9c..142fad11ac 100644 --- a/tests_cypress/cypress/support/commands.js +++ b/tests_cypress/cypress/support/commands.js @@ -99,7 +99,7 @@ Cypress.Commands.add('getByTestId', (selector, ...args) => { }); Cypress.Commands.add('login', (un, password, agreeToTerms = true) => { - cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET') }).then((acct) => { + cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET'), pw: Cypress.env('NOTIFY_PASSWORD') }).then((acct) => { cy.session([acct.email_address, password, agreeToTerms], () => { LoginPage.Login(acct.email_address, password, agreeToTerms); }); From fb5bd26cfc75be0c9da002d6382516c50e7790a9 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Thu, 19 Sep 2024 08:40:34 -0300 Subject: [PATCH 10/38] feat(config): simplify config --- tests_cypress/config.js | 70 +++++++---------------------------------- 1 file changed, 11 insertions(+), 59 deletions(-) diff --git a/tests_cypress/config.js b/tests_cypress/config.js index 9871064e94..5046885b50 100644 --- a/tests_cypress/config.js +++ b/tests_cypress/config.js @@ -1,3 +1,12 @@ +let COMMON = { + Services: { + Cypress: 'd4e8a7f4-2b8a-4c9a-8b3f-9c2d4e8a7f4b' + }, + Templates: { + 'SMOKE_TEST_EMAIL': 'f47ac10b-58cc-4372-a567-0e02b2c3d479', + }, +}; + let STAGING = { CONFIG_NAME: "STAGING", Hostnames: { @@ -5,35 +14,6 @@ let STAGING = { Admin: 'https://staging.notification.cdssandbox.xyz', DDAPI: 'https://api.document.staging.notification.cdssandbox.xyz', }, - Services: { - Notify: 'd6aa2c68-a2d9-4437-ab19-3ae8eb202553', - Cypress: '5c8a0501-2aa8-433a-ba51-cefb8063ab93' - }, - Templates: { - 'FILE_ATTACH_TEMPLATE_ID': '7246c71e-3d60-458b-96af-af17a5b07659', - 'SIMPLE_EMAIL_TEMPLATE_ID': '939dafde-1b60-47f0-a6d5-c9080d92a4a8', - 'VARIABLES_EMAIL_TEMPLATE_ID': '1101a00a-11b7-4036-865c-add43fcff7c9', - 'SMOKE_TEST_EMAIL': '5e26fae6-3565-44d5-bfed-b18680b6bd39', - 'SMOKE_TEST_EMAIL_BULK': '04145882-0f21-4d57-940d-69883fc23e77', - 'SMOKE_TEST_EMAIL_ATTACH': 'bf85def8-01b4-4c72-98a8-86f2bc10f2a4', - 'SMOKE_TEST_EMAIL_LINK': '37924e87-038d-48b8-b122-f6dddefd56d5', - 'SMOKE_TEST_SMS': '16cae0b3-1d44-47ad-a537-fd12cc0646b6' - }, - Users: { - Team: ['andrew.leith+bannertest@cds-snc.ca'], - NonTeam: ['person@example.com'], - Simulated: ['simulate-delivered-2@notification.canada.ca', 'simulate-delivered-3@notification.canada.ca', 'success@simulator.amazonses.com'], - SimulatedPhone: ['+16132532222', '+16132532223', '+16132532224'] - }, - Organisations: { - 'DEFAULT_ORG_ID': '4eef762f-383d-4068-81ca-c2c5c186eb16', - 'NO_CUSTOM_BRANDING_ORG_ID': '4eef762f-383d-4068-81ca-c2c5c186eb16' - }, - ReplyTos: { - Default: '24e5288d-8bfa-4ad4-93aa-592c11a694cd', - Second: '797865c4-788b-4184-91ae-8e45eb07e40b' - }, - viewports: [320, 375, 640, 768] }; let LOCAL = { @@ -43,43 +23,15 @@ let LOCAL = { Admin: 'http://localhost:6012', DDAPI: 'http://localhost:7000', }, - Services: { - Notify: 'd6aa2c68-a2d9-4437-ab19-3ae8eb202553', - Cypress: '5c8a0501-2aa8-433a-ba51-cefb8063ab93' - }, - Templates: { - 'FILE_ATTACH_TEMPLATE_ID': 'e52acc48-dcb9-4f70-81cf-b87d0ceaef1b', - 'SIMPLE_EMAIL_TEMPLATE_ID': '0894dc6c-1b07-465e-91f0-aa76f202a83f', - 'VARIABLES_EMAIL_TEMPLATE_ID': 'fa00aa13-87fd-4bc7-9349-ba9270347055', - 'SMOKE_TEST_EMAIL': '08673acf-fef1-408d-8ce7-7809907595b2', - 'SMOKE_TEST_EMAIL_BULK': 'efbd319b-4de8-41c7-850f-93ec0490d3c2', - 'SMOKE_TEST_EMAIL_ATTACH': 'cbd5307f-8662-4cea-9b8e-3bc672bf005c', - 'SMOKE_TEST_EMAIL_LINK': '94cce202-b171-440f-b0c1-734368ca9494', - 'SMOKE_TEST_SMS': 'a9fff158-a745-417a-b1ec-ceebcba6614f' - }, - Users: { - Team: ['william.banks+admin@cds-snc.ca'], - NonTeam: ['person@example.com'], - Simulated: ['simulate-delivered-2@notification.canada.ca', 'simulate-delivered-3@notification.canada.ca', 'success@simulator.amazonses.com'], - SimulatedPhone: ['+16132532222', '+16132532223', '+16132532224'] - }, - Organisations: { - 'DEFAULT_ORG_ID': 'ff9e5ddd-926f-4ae2-bc87-f5104262ca17', - 'NO_CUSTOM_BRANDING_ORG_ID': '39b3230e-300a-42f4-bfb7-40b20b704d44' - }, - ReplyTos: { - Default: '8c2a9b22-8fec-4ad9-bca8-658abbb7406e', - Second: 'fc4d2266-5594-47d0-8056-7bef62d59177' - }, - viewports: [320, 375, 640, 768] }; const config = { + COMMON, STAGING, LOCAL, }; // choose which config to use here -const ConfigToUse = config.STAGING; +const ConfigToUse = { ...config.COMMON, ...config.LOCAL }; module.exports = ConfigToUse; \ No newline at end of file From 1d3bd6248cf4239697298dc2157e1c66bc4c7b12 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Thu, 19 Sep 2024 08:41:11 -0300 Subject: [PATCH 11/38] fix up ids --- tests_cypress/cypress/e2e/admin/login.cy.js | 2 +- tests_cypress/cypress/e2e/admin/qualtrics.cy.js | 2 +- tests_cypress/cypress/support/commands.js | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests_cypress/cypress/e2e/admin/login.cy.js b/tests_cypress/cypress/e2e/admin/login.cy.js index 841a98f218..7d61cac772 100644 --- a/tests_cypress/cypress/e2e/admin/login.cy.js +++ b/tests_cypress/cypress/e2e/admin/login.cy.js @@ -32,7 +32,7 @@ describe("Basic login", () => { }); it("displays notify service page", () => { - cy.visit(`/services/${config.Services.Notify}`); + cy.visit(`/services/${config.Services.Cypress}`); cy.contains("h1", "Dashboard").should("be.visible"); }); }); diff --git a/tests_cypress/cypress/e2e/admin/qualtrics.cy.js b/tests_cypress/cypress/e2e/admin/qualtrics.cy.js index 9e11c676ca..265a74f04c 100644 --- a/tests_cypress/cypress/e2e/admin/qualtrics.cy.js +++ b/tests_cypress/cypress/e2e/admin/qualtrics.cy.js @@ -17,7 +17,7 @@ describe("Qualtrics", () => { }); it("survey button appears and survey opens", () => { - cy.visit(`/services/${config.Services.Notify}`); + cy.visit(`/services/${config.Services.Cypress}`); cy.contains("h1", "Dashboard").should("be.visible"); cy.get("#QSIFeedbackButton-btn").should("be.visible"); // qualtrics survey button cy.get("#QSIFeedbackButton-btn").click(); // click the button diff --git a/tests_cypress/cypress/support/commands.js b/tests_cypress/cypress/support/commands.js index 142fad11ac..afe863be79 100644 --- a/tests_cypress/cypress/support/commands.js +++ b/tests_cypress/cypress/support/commands.js @@ -99,9 +99,9 @@ Cypress.Commands.add('getByTestId', (selector, ...args) => { }); Cypress.Commands.add('login', (un, password, agreeToTerms = true) => { - cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET'), pw: Cypress.env('NOTIFY_PASSWORD') }).then((acct) => { - cy.session([acct.email_address, password, agreeToTerms], () => { - LoginPage.Login(acct.email_address, password, agreeToTerms); + //cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET'), pw: Cypress.env('NOTIFY_PASSWORD') }).then((acct) => { + cy.session([un, password, agreeToTerms], () => { + LoginPage.Login(un, password, agreeToTerms); }); - }); + //}); }); From f199ad48152f17008dc87cb402ef25a151455261 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 20 Sep 2024 11:51:52 -0300 Subject: [PATCH 12/38] chore(refactor): refactor login command; add login command for platform admin --- .../cypress/e2e/admin/a11y/app_pages.cy.js | 2 +- .../cypress/e2e/admin/branding/a11y.cy.js | 2 +- .../admin/branding/branding-settings.cy.js | 2 +- .../e2e/admin/branding/edit-branding.cy.js | 2 +- .../e2e/admin/branding/request-branding.cy.js | 2 +- .../e2e/admin/branding/review-pool.cy.js | 2 +- .../e2e/admin/menu/disclosure_menu.cy.js | 2 +- .../cypress/e2e/admin/service-settings.cy.js | 2 +- .../cypress/e2e/admin/sign_out/sign_out.cy.js | 2 +- .../cypress/e2e/admin/sitemap/sitemap.cy.js | 6 +++--- .../e2e/admin/template-categories.cy.js | 2 +- .../cypress/e2e/admin/tou_prompt.cy.js | 8 ++++---- tests_cypress/cypress/support/commands.js | 20 ++++++++++++++----- 13 files changed, 32 insertions(+), 22 deletions(-) diff --git a/tests_cypress/cypress/e2e/admin/a11y/app_pages.cy.js b/tests_cypress/cypress/e2e/admin/a11y/app_pages.cy.js index 504a832503..ef0344a946 100644 --- a/tests_cypress/cypress/e2e/admin/a11y/app_pages.cy.js +++ b/tests_cypress/cypress/e2e/admin/a11y/app_pages.cy.js @@ -82,7 +82,7 @@ const pages = [ describe(`A11Y - App pages [${config.CONFIG_NAME}]`, () => { for (const page of pages) { it(`${page.name}`, () => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.a11yScan(page.route, { a11y: true, htmlValidate: true, diff --git a/tests_cypress/cypress/e2e/admin/branding/a11y.cy.js b/tests_cypress/cypress/e2e/admin/branding/a11y.cy.js index a29898c772..5f336d03db 100644 --- a/tests_cypress/cypress/e2e/admin/branding/a11y.cy.js +++ b/tests_cypress/cypress/e2e/admin/branding/a11y.cy.js @@ -13,7 +13,7 @@ describe("Branding A11Y", () => { // stop the recurring dashboard fetch requests cy.intercept("GET", "**/dashboard.json", {}); - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); }); // perform a11yScan on all pages in the branding_pages array diff --git a/tests_cypress/cypress/e2e/admin/branding/branding-settings.cy.js b/tests_cypress/cypress/e2e/admin/branding/branding-settings.cy.js index 8b39a101d8..c99f6e7c63 100644 --- a/tests_cypress/cypress/e2e/admin/branding/branding-settings.cy.js +++ b/tests_cypress/cypress/e2e/admin/branding/branding-settings.cy.js @@ -9,7 +9,7 @@ describe("Branding settings", () => { // stop the recurring dashboard fetch requests cy.intercept("GET", "**/dashboard.json", {}); - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit(`/services/${config.Services.Cypress}/service-settings`); }); diff --git a/tests_cypress/cypress/e2e/admin/branding/edit-branding.cy.js b/tests_cypress/cypress/e2e/admin/branding/edit-branding.cy.js index be87beb392..0372b11faf 100644 --- a/tests_cypress/cypress/e2e/admin/branding/edit-branding.cy.js +++ b/tests_cypress/cypress/e2e/admin/branding/edit-branding.cy.js @@ -11,7 +11,7 @@ describe("Edit Branding", () => { // stop the recurring dashboard fetch requests cy.intercept("GET", "**/dashboard.json", {}); - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit(`/services/${config.Services.Cypress}/edit-branding`); }); diff --git a/tests_cypress/cypress/e2e/admin/branding/request-branding.cy.js b/tests_cypress/cypress/e2e/admin/branding/request-branding.cy.js index 2f22d3ce30..099b6c90be 100644 --- a/tests_cypress/cypress/e2e/admin/branding/request-branding.cy.js +++ b/tests_cypress/cypress/e2e/admin/branding/request-branding.cy.js @@ -8,7 +8,7 @@ describe("Branding request", () => { beforeEach(() => { // stop the recurring dashboard fetch requests cy.intercept("GET", "**/dashboard.json", {}); - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit(`/services/${config.Services.Cypress}/branding-request`); }); diff --git a/tests_cypress/cypress/e2e/admin/branding/review-pool.cy.js b/tests_cypress/cypress/e2e/admin/branding/review-pool.cy.js index 2247e3ef27..175cc32887 100755 --- a/tests_cypress/cypress/e2e/admin/branding/review-pool.cy.js +++ b/tests_cypress/cypress/e2e/admin/branding/review-pool.cy.js @@ -9,7 +9,7 @@ import { describe("Review Pool", () => { beforeEach(() => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit(`/services/${config.Services.Cypress}/review-pool`); }); context("General page functionality", () => { diff --git a/tests_cypress/cypress/e2e/admin/menu/disclosure_menu.cy.js b/tests_cypress/cypress/e2e/admin/menu/disclosure_menu.cy.js index d0f44e79fc..8bddd841eb 100644 --- a/tests_cypress/cypress/e2e/admin/menu/disclosure_menu.cy.js +++ b/tests_cypress/cypress/e2e/admin/menu/disclosure_menu.cy.js @@ -134,7 +134,7 @@ describe("Mobile menu", () => { }); it("Re-focus on the menu button when the menu closes (signed in)", () => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit("/"); MainMenu.OpenMenu(); diff --git a/tests_cypress/cypress/e2e/admin/service-settings.cy.js b/tests_cypress/cypress/e2e/admin/service-settings.cy.js index 42005cca5c..1a95814b5e 100644 --- a/tests_cypress/cypress/e2e/admin/service-settings.cy.js +++ b/tests_cypress/cypress/e2e/admin/service-settings.cy.js @@ -6,7 +6,7 @@ import { ServiceSettingsPage } from "../../Notify/Admin/Pages/all"; describe("Service Settings", () => { // Login to notify before the test suite starts before(() => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); }); beforeEach(() => { diff --git a/tests_cypress/cypress/e2e/admin/sign_out/sign_out.cy.js b/tests_cypress/cypress/e2e/admin/sign_out/sign_out.cy.js index 9d45b2df5b..5f253c5bdf 100644 --- a/tests_cypress/cypress/e2e/admin/sign_out/sign_out.cy.js +++ b/tests_cypress/cypress/e2e/admin/sign_out/sign_out.cy.js @@ -16,7 +16,7 @@ describe("Sign out", () => { it("Redirects to session timeout page when logged in (multiple pages)", () => { ["/home", "/features"].forEach((page) => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); vistPageAndFastForwardTime(page); // asserts diff --git a/tests_cypress/cypress/e2e/admin/sitemap/sitemap.cy.js b/tests_cypress/cypress/e2e/admin/sitemap/sitemap.cy.js index 32a44f2045..e0ae27d470 100644 --- a/tests_cypress/cypress/e2e/admin/sitemap/sitemap.cy.js +++ b/tests_cypress/cypress/e2e/admin/sitemap/sitemap.cy.js @@ -54,7 +54,7 @@ describe(`Sitemap`, () => { }); it("Does display the 'You' group when logged in", () => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit(path); cy.getByTestId("sitemap-group").contains("Your GC Notify"); @@ -75,13 +75,13 @@ describe(`Sitemap`, () => { cy.get('a[href="/sitemap"]').should("be.visible"); }); it("Has the sitemap link on app pages when logged in", () => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit("/activity"); cy.get(`#${sitemap_footer_id}`).should("be.visible"); }); it("Has the sitemap link on GCA pages when logged in", () => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit("/features"); cy.get('a[href="/sitemap"]').should("be.visible"); diff --git a/tests_cypress/cypress/e2e/admin/template-categories.cy.js b/tests_cypress/cypress/e2e/admin/template-categories.cy.js index cb7b5d7609..90aac97900 100644 --- a/tests_cypress/cypress/e2e/admin/template-categories.cy.js +++ b/tests_cypress/cypress/e2e/admin/template-categories.cy.js @@ -5,7 +5,7 @@ import { TemplatesPage as Page } from "../../Notify/Admin/Pages/all"; describe("Template categories", () => { beforeEach(() => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit(`/services/${config.Services.Cypress}/templates`); }); diff --git a/tests_cypress/cypress/e2e/admin/tou_prompt.cy.js b/tests_cypress/cypress/e2e/admin/tou_prompt.cy.js index 946b91ef40..8994c0cb17 100644 --- a/tests_cypress/cypress/e2e/admin/tou_prompt.cy.js +++ b/tests_cypress/cypress/e2e/admin/tou_prompt.cy.js @@ -2,7 +2,7 @@ import TouPrompt from "../../Notify/Admin/Pages/TouPrompt"; describe("TOU Prompt", () => { it("should display the prompt when logged in", () => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD"), false); + cy.login(false); cy.visit("/"); TouPrompt.Components.Prompt().should("be.visible"); @@ -11,7 +11,7 @@ describe("TOU Prompt", () => { }); it("should not display the prompt after being dismissed", () => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD"), false); + cy.login(false); cy.visit("/"); TouPrompt.Components.Prompt().should("be.visible"); @@ -35,7 +35,7 @@ describe("TOU Prompt", () => { cy.visit("/security"); TouPrompt.Components.Prompt().should("not.exist"); - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD"), false); + cy.login(false); cy.visit("/features"); TouPrompt.Components.Prompt().should("not.exist"); @@ -45,7 +45,7 @@ describe("TOU Prompt", () => { }); it("should display the prompt again when navigating to the page before prompt is dismissed", () => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD"), false); + cy.login(false); cy.visit("/"); TouPrompt.Components.Prompt().should("be.visible"); diff --git a/tests_cypress/cypress/support/commands.js b/tests_cypress/cypress/support/commands.js index afe863be79..3f05168c64 100644 --- a/tests_cypress/cypress/support/commands.js +++ b/tests_cypress/cypress/support/commands.js @@ -98,10 +98,20 @@ Cypress.Commands.add('getByTestId', (selector, ...args) => { return cy.get(`[data-testid=${selector}]`, ...args) }); -Cypress.Commands.add('login', (un, password, agreeToTerms = true) => { - //cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET'), pw: Cypress.env('NOTIFY_PASSWORD') }).then((acct) => { - cy.session([un, password, agreeToTerms], () => { - LoginPage.Login(un, password, agreeToTerms); +Cypress.Commands.add('login', (agreeToTerms = true) => { + cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET') }).then((acct) => { + cy.log('acct', acct); + cy.session([acct.regular.email_address, agreeToTerms], () => { + LoginPage.Login(acct.regular.email_address, Cypress.env('NOTIFY_PASSWORD'), agreeToTerms); }); - //}); + }); }); + + +Cypress.Commands.add('loginAsPlatformAdmin', (agreeToTerms = true) => { + cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET') }).then((acct) => { + cy.session([acct.admin.email_address, agreeToTerms], () => { + LoginPage.Login(acct.admin.email_address, Cypress.env('NOTIFY_PASSWORD'), agreeToTerms); + }); + }); +}); \ No newline at end of file From c987242e5e31017bd0ee8a5f4d283bf420329926 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 20 Sep 2024 11:52:19 -0300 Subject: [PATCH 13/38] task(cypress config): add back SMS template ID --- tests_cypress/config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests_cypress/config.js b/tests_cypress/config.js index 5046885b50..cc105f6d9e 100644 --- a/tests_cypress/config.js +++ b/tests_cypress/config.js @@ -4,6 +4,7 @@ let COMMON = { }, Templates: { 'SMOKE_TEST_EMAIL': 'f47ac10b-58cc-4372-a567-0e02b2c3d479', + 'SMOKE_TEST_SMS': 'e4b8f8d0-6a3b-4b9e-8c2b-1f2d3e4a5b6c', }, }; From ac9019a9a1e2ec5167581c5be0a1c652df893c67 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 20 Sep 2024 11:52:48 -0300 Subject: [PATCH 14/38] fix(tou_prompt test): add assertion to ensure success of agreeing to terms --- tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js b/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js index ee9e0d1791..2b5ab73363 100644 --- a/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js +++ b/tests_cypress/cypress/Notify/Admin/Pages/TouPrompt.js @@ -15,6 +15,8 @@ let Actions = { // depending on how many services a user has, the app either goes to the /accounts page // or to a specific service page - either means success cy.url().should('match', /\/(accounts|services)/); + cy.get('h1').should('not.contain', 'Before you continue'); + }, }; From b79f8a0a5b54a8ce0f67bd33c4f9bb1782273426 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 20 Sep 2024 11:54:16 -0300 Subject: [PATCH 15/38] fix(create-account): simplify call to api; remove posting of the password since API already has this secret --- tests_cypress/cypress/plugins/create-account.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests_cypress/cypress/plugins/create-account.js b/tests_cypress/cypress/plugins/create-account.js index fe79a35de7..92ffadc0ea 100644 --- a/tests_cypress/cypress/plugins/create-account.js +++ b/tests_cypress/cypress/plugins/create-account.js @@ -24,23 +24,19 @@ const Utilities = { } }; -const createAccount = async (baseUrl, username, secret, pw) => { +const createAccount = async (baseUrl, username, secret) => { // return a generated id const token = Utilities.CreateJWT(username, secret); const generatedUsername = Utilities.GenerateID(10); const url = `${baseUrl}/cypress/create_user/${generatedUsername}`; return new Promise((resolve, reject) => { - const postData = JSON.stringify({ - password: pw - }); - const options = { method: 'POST', headers: { Authorization: `Bearer ${token}`, "Content-Type": 'application/json', - 'Content-Length': Buffer.byteLength(postData) + 'Content-Length': 0 }, }; @@ -69,8 +65,6 @@ const createAccount = async (baseUrl, username, secret, pw) => { reject(error); // Reject the promise on request error }); - // Write the POST parameters to the request body - req.write(postData); req.end(); }); }; From 77c143af98f9502920d84e0d21f4e78c7006a6f3 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 20 Sep 2024 11:54:35 -0300 Subject: [PATCH 16/38] chore(email-account): remove debug logging --- tests_cypress/cypress/plugins/email-account.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests_cypress/cypress/plugins/email-account.js b/tests_cypress/cypress/plugins/email-account.js index 3fc7d24f05..6f8a4a8f00 100644 --- a/tests_cypress/cypress/plugins/email-account.js +++ b/tests_cypress/cypress/plugins/email-account.js @@ -90,7 +90,6 @@ const emailAccount = async () => { const messages = await connection.search(searchCriteria, fetchOptions); if (!messages.length) { - console.log('Cannot find any emails'); return null; } else { let latestMail = null; @@ -109,7 +108,6 @@ const emailAccount = async () => { } } - console.log('deleting', uidsToDelete); try { await connection.deleteMessage(uidsToDelete); await connection.imap.expunge(); From 36bfe458ff568885481a08084100bf8ee058378b Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Mon, 23 Sep 2024 08:39:05 -0300 Subject: [PATCH 17/38] fix: add template category to the test that will be empty for email --- .../cypress/e2e/admin/template-filters.cy.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests_cypress/cypress/e2e/admin/template-filters.cy.js b/tests_cypress/cypress/e2e/admin/template-filters.cy.js index ee675f55fd..64fed43183 100644 --- a/tests_cypress/cypress/e2e/admin/template-filters.cy.js +++ b/tests_cypress/cypress/e2e/admin/template-filters.cy.js @@ -9,8 +9,13 @@ const types = { }; const categories = { - en: ["Test"], - fr: ["Test"], + en: ["Other"], + fr: ["Autre"], +}; + +const catEmpty = { + en: "Authentication", + fr: "Authentification", }; describe("Template filters", () => { @@ -161,8 +166,8 @@ describe("Template filters", () => { Page.Components.EmptyState().should("not.be.visible"); Page.ToggleFilters(); - Page.ApplyTypeFilter(types[lang][1]); - Page.ApplyCategoryFilter(categories[lang][0]); + Page.ApplyTypeFilter(types[lang][0]); + Page.ApplyCategoryFilter(catEmpty[lang]); // Empty state should be visible Page.Components.EmptyState().should("be.visible"); From 213e7e4c3a3c79d7b43b0704f84db2fd959da5e4 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Mon, 23 Sep 2024 09:10:21 -0300 Subject: [PATCH 18/38] fix(create-account): remove pw prop --- tests_cypress/cypress.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests_cypress/cypress.config.js b/tests_cypress/cypress.config.js index 667004ff06..1221430303 100644 --- a/tests_cypress/cypress.config.js +++ b/tests_cypress/cypress.config.js @@ -38,11 +38,11 @@ module.exports = defineConfig({ fetchEmail(acct) { return emailAccount.fetchEmail(acct) }, - createAccount({ baseUrl, username, secret, pw }) { + createAccount({ baseUrl, username, secret }) { if (global.acct) { return global.acct; } else { - let acct = CreateAccount(baseUrl, username, secret, pw); + let acct = CreateAccount(baseUrl, username, secret); global.acct = acct; return acct } From 689222bee46e9e1572b23c19310886f61de2c5fb Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 27 Sep 2024 11:34:48 -0300 Subject: [PATCH 19/38] chore: remove debug log --- tests_cypress/cypress/support/commands.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests_cypress/cypress/support/commands.js b/tests_cypress/cypress/support/commands.js index 3f05168c64..7fdf72b89c 100644 --- a/tests_cypress/cypress/support/commands.js +++ b/tests_cypress/cypress/support/commands.js @@ -100,7 +100,6 @@ Cypress.Commands.add('getByTestId', (selector, ...args) => { Cypress.Commands.add('login', (agreeToTerms = true) => { cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET') }).then((acct) => { - cy.log('acct', acct); cy.session([acct.regular.email_address, agreeToTerms], () => { LoginPage.Login(acct.regular.email_address, Cypress.env('NOTIFY_PASSWORD'), agreeToTerms); }); From b3082b55da5426a163d803e49a8c4ca51c5df76e Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 27 Sep 2024 11:35:19 -0300 Subject: [PATCH 20/38] fix: dont try to delete emails when there is none --- tests_cypress/cypress/plugins/email-account.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests_cypress/cypress/plugins/email-account.js b/tests_cypress/cypress/plugins/email-account.js index 6f8a4a8f00..7848054ea8 100644 --- a/tests_cypress/cypress/plugins/email-account.js +++ b/tests_cypress/cypress/plugins/email-account.js @@ -109,10 +109,12 @@ const emailAccount = async () => { } try { - await connection.deleteMessage(uidsToDelete); - await connection.imap.expunge(); + if (uidsToDelete.length > 0) { + await connection.deleteMessage(uidsToDelete); + await connection.imap.expunge(); + } } catch (e) { - console.error('delete error', e); + console.error('delete error', uidsToDelete, e); } return latestMail; From 8e066123f2875703a0643b53542f862ac6f8dec7 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 27 Sep 2024 11:36:32 -0300 Subject: [PATCH 21/38] fix: update calls to login across tests --- .../admin/platform_admin/template-categories.cy.js | 2 +- .../cypress/e2e/admin/template-filters.cy.js | 2 +- .../e2e/admin/template/create-template.cy.js | 14 ++++---------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/tests_cypress/cypress/e2e/admin/platform_admin/template-categories.cy.js b/tests_cypress/cypress/e2e/admin/platform_admin/template-categories.cy.js index f04ab9d49c..5fb7e8f546 100644 --- a/tests_cypress/cypress/e2e/admin/platform_admin/template-categories.cy.js +++ b/tests_cypress/cypress/e2e/admin/platform_admin/template-categories.cy.js @@ -9,7 +9,7 @@ import { Admin } from "../../../Notify/NotifyAPI"; describe("Template Categories", () => { beforeEach(() => { - cy.login(Cypress.env("NOTIFY_ADMIN_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.loginAsPlatformAdmin(); cy.visit(`/template-categories`); }); diff --git a/tests_cypress/cypress/e2e/admin/template-filters.cy.js b/tests_cypress/cypress/e2e/admin/template-filters.cy.js index 64fed43183..50a4a446c6 100644 --- a/tests_cypress/cypress/e2e/admin/template-filters.cy.js +++ b/tests_cypress/cypress/e2e/admin/template-filters.cy.js @@ -20,7 +20,7 @@ const catEmpty = { describe("Template filters", () => { beforeEach(() => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); }); ["en", "fr"].forEach((lang) => { diff --git a/tests_cypress/cypress/e2e/admin/template/create-template.cy.js b/tests_cypress/cypress/e2e/admin/template/create-template.cy.js index 8dd7e54c82..d3055242d3 100644 --- a/tests_cypress/cypress/e2e/admin/template/create-template.cy.js +++ b/tests_cypress/cypress/e2e/admin/template/create-template.cy.js @@ -7,7 +7,7 @@ import { Admin } from "../../../Notify/NotifyAPI"; describe("Create Template", () => { context.skip("FF_TEMPLATE_CATEGORY - OFF", () => { it("Process type defaults to bulk if non-admin", () => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit(`/services/${config.Services.Cypress}/templates`); TemplatesPage.CreateTemplate(); @@ -40,10 +40,7 @@ describe("Create Template", () => { }); it.skip("Process type defaults to bulk if admin", () => { - cy.login( - Cypress.env("NOTIFY_ADMIN_USER"), - Cypress.env("NOTIFY_PASSWORD"), - ); + cy.loginAsPlatformAdmin(); cy.visit(`/services/${config.Services.Cypress}/templates`); TemplatesPage.CreateTemplate(); @@ -78,7 +75,7 @@ describe("Create Template", () => { context("FF_TEMPLATE_CATEGORY - ON", () => { it("Process type should be null and the category process type should be used if non-admin", () => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit(`/services/${config.Services.Cypress}/templates`); TemplatesPage.CreateTemplate(); TemplatesPage.SelectTemplateType("email"); @@ -110,10 +107,7 @@ describe("Create Template", () => { }); it("Process type should be null and the category process type should be used if admin", () => { - cy.login( - Cypress.env("NOTIFY_ADMIN_USER"), - Cypress.env("NOTIFY_PASSWORD"), - ); + cy.loginAsPlatformAdmin(); cy.visit(`/services/${config.Services.Cypress}/templates`); TemplatesPage.CreateTemplate(); TemplatesPage.SelectTemplateType("email"); From 9a7d00d03e0e48c5ce722c56de309fb0b919fe10 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 27 Sep 2024 11:36:43 -0300 Subject: [PATCH 22/38] chore: update test and get values from config --- .../Notify/Admin/Pages/TemplatesPage.js | 3 ++ .../e2e/admin/template/edit-template.cy.js | 51 +++++-------------- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/tests_cypress/cypress/Notify/Admin/Pages/TemplatesPage.js b/tests_cypress/cypress/Notify/Admin/Pages/TemplatesPage.js index 2f3d0bb36b..741a6a24cb 100644 --- a/tests_cypress/cypress/Notify/Admin/Pages/TemplatesPage.js +++ b/tests_cypress/cypress/Notify/Admin/Pages/TemplatesPage.js @@ -36,6 +36,9 @@ let Actions = { cy.contains('a', template_name).first().click(); cy.contains('h1', template_name).should('be.visible'); }, + SelectTemplateById: (service_id, template_id) => { + cy.get(`a[href="/services/${service_id}/templates/${template_id}"]`).click(); + }, GotoAddRecipients: () => { Components.YesAddRecipients().click(); //cy.contains('h1', 'Add recipients').should('be.visible'); diff --git a/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js b/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js index 18d1848a4f..4b4b5ea1a4 100644 --- a/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js +++ b/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js @@ -4,18 +4,6 @@ import config from "../../../../config"; import { TemplatesPage as Page } from "../../../Notify/Admin/Pages/all"; import { Admin } from "../../../Notify/NotifyAPI"; -// TODO: dont hardcode these -const templates = { - smoke_test_email: { - name: "SMOKE_TEST_EMAIL", - id: "5e26fae6-3565-44d5-bfed-b18680b6bd39", - }, - smoke_test_email_attach: { - name: "SMOKE_TEST_EMAIL_ATTACH", - id: "bf85def8-01b4-4c72-98a8-86f2bc10f2a4", - }, -}; - const categories = { OTHER: "Other", AUTH: "Authentication", @@ -28,21 +16,18 @@ describe("Edit template", () => { // Override the process_type -> new process type should be saved for an existing template it("Should allow platform admin to override process type", () => { // login as admin - cy.login( - Cypress.env("NOTIFY_ADMIN_USER"), - Cypress.env("NOTIFY_PASSWORD"), - ); + cy.loginAsPlatformAdmin(); cy.visit(`/services/${config.Services.Cypress}/templates`); // set template priority to use TC - Page.SelectTemplate(templates.smoke_test_email.name); + Page.SelectTemplateById(config.Services.Cypress, config.Templates.SMOKE_TEST_SMS); Page.EditCurrentTemplate(); Page.SetTemplatePriority("bulk"); Page.SaveTemplate(); - + // use api to check that it was set Admin.GetTemplate({ - templateId: templates.smoke_test_email.id, + templateId: config.Templates.SMOKE_TEST_SMS, serviceId: config.Services.Cypress, }).then((response) => { console.log("response", response); @@ -56,7 +41,7 @@ describe("Edit template", () => { // use api to check that it was overridden Admin.GetTemplate({ - templateId: templates.smoke_test_email.id, + templateId: config.Templates.SMOKE_TEST_SMS, serviceId: config.Services.Cypress, }).then((response) => { console.log("response", response); @@ -70,7 +55,7 @@ describe("Edit template", () => { // use api to check that it was overridden Admin.GetTemplate({ - templateId: templates.smoke_test_email.id, + templateId: config.Templates.SMOKE_TEST_SMS, serviceId: config.Services.Cypress, }).then((response) => { console.log("response", response); @@ -83,7 +68,7 @@ describe("Edit template", () => { const template_name = "Test Template"; // seed data - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit(`/services/${config.Services.Cypress}/templates`); Page.CreateTemplate(); Page.SelectTemplateType("email"); @@ -125,16 +110,14 @@ describe("Edit template", () => { context("FF ON", () => { // Override the process_type -> new process type should be saved for an existing template it("Should allow platform admin to override process type", () => { + cy.log("CONMFIG", config); // Admin user 1. // login as admin - cy.login( - Cypress.env("NOTIFY_ADMIN_USER"), - Cypress.env("NOTIFY_PASSWORD"), - ); + cy.loginAsPlatformAdmin(); cy.visit(`/services/${config.Services.Cypress}/templates`); // set template priority to use TC - Page.SelectTemplate(templates.smoke_test_email_attach.name); + Page.SelectTemplateById(config.Services.Cypress, config.Templates.SMOKE_TEST_EMAIL); Page.EditCurrentTemplate(); Page.Components.TemplateSubject().type("a"); Page.SetTemplatePriority("bulk"); @@ -142,7 +125,7 @@ describe("Edit template", () => { // use api to check that it was set Admin.GetTemplate({ - templateId: templates.smoke_test_email_attach.id, + templateId: config.Templates.SMOKE_TEST_SMS, serviceId: config.Services.Cypress, }).then((response) => { console.log("response", response); @@ -151,7 +134,7 @@ describe("Edit template", () => { }); it("Should set process_type to null and use category's process_type when non-admin changes a template's category", () => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit(`/services/${config.Services.Cypress}/templates`); // Seed data with a template before we start with the test. @@ -184,10 +167,7 @@ describe("Edit template", () => { }); it("Should override process_type when a template has a category and user is admin", () => { - cy.login( - Cypress.env("NOTIFY_ADMIN_USER"), - Cypress.env("NOTIFY_PASSWORD"), - ); + cy.loginAsPlatformAdmin(); cy.visit(`/services/${config.Services.Cypress}/templates`); // Seed data with a template before we start with the test. @@ -219,10 +199,7 @@ describe("Edit template", () => { }); it("Should set the process type to null when a category is changed and user is admin", () => { - cy.login( - Cypress.env("NOTIFY_ADMIN_USER"), - Cypress.env("NOTIFY_PASSWORD"), - ); + cy.loginAsPlatformAdmin(); cy.visit(`/services/${config.Services.Cypress}/templates`); // seed data with a template before we start with the test. From 6978d521294ff3e2e1206066828252ea04a8cab9 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 4 Oct 2024 13:58:28 +0000 Subject: [PATCH 23/38] chore: add README, extra npm script --- tests_cypress/README.md | 44 ++++++++++++++++++++++++++++++++++++++ tests_cypress/package.json | 3 ++- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests_cypress/README.md diff --git a/tests_cypress/README.md b/tests_cypress/README.md new file mode 100644 index 0000000000..f150ad9ff2 --- /dev/null +++ b/tests_cypress/README.md @@ -0,0 +1,44 @@ +# Notify + Cypress 🎉 + +## Setup +This folder contains Cypress tests suites. In order to run them, you'll need to install cypress and its dependencies. If you're running inside the dev container, rebuild your dev container to get the necessary packages. + +## Running the tests +### In your devcontainer +There are some issues getting the cypress UI to launch within the devcontainer. For now, you can run the headless tests inside the dev container but if you want to launch the cypress UI you will need to do that outside of the dev container. + +There are 3 helper scripts in `package.json` to run 2 of the test suites. Run these from the `tests_cypress/` folder: +- `npm run cypress`: this will open Cypress with its UI and you can choose any test suite to run +- `npm run a11y`: this will run the accessibility tests in headless mode using the electron browser +- `npm run ci`: this will run the headless CI tests in headless mode using the electron browser + +### Outside of your devcontainer +To launch the cypress UI, where you can choose your test suite and visually debug and inspect tests, run (from the `tests_cypress/` folder): +- `npm run cypress`: this will open the cypress UI where you can choose which tests to run and in which browser + +### Local installation +To install cypress locally, use the following command, from the `tests_cypress/` folder: +```bash +npm install +npx cypress install +``` + +## Configuration +- `cypress.env.json`: this file contains sensitive items like api keys and passphrases that you'll need to run the tests. You'll need to add the file `cypress.env.json` into the `tests_cypress/` folder and its contents can be found in 1password. +- `config.js`: this file contains non-sensitive items like template ids and hostnames that you'll need to run the tests + +### `cypress.env.json` contents +| key | description | +| --------------- | ----------------------------------------------- | +| ADMIN_SECRET | Secret admin uses to authenticate against API | +| ADMIN_USERNAME | Username admin uses to authenticate against API | +| NOTIFY_USER | Notify user used by the tests | +| NOTIFY_PASSWORD | Password of NOTIFY_USER | +| IMAP_PASSWORD | IMAP password of gmail account for NOTIFY_USER | + +### Target environment 🎯 +The tests are configured to run against the staging environment by default. To run the tests against your local environment, you'll need to create a local service and API keys and store these values in your config. You will also need to update the `ConfigToUse` variable in `config.js` file: +```js +const ConfigToUse = config.LOCAL; +``` + diff --git a/tests_cypress/package.json b/tests_cypress/package.json index 2711201a62..1af308a8e6 100644 --- a/tests_cypress/package.json +++ b/tests_cypress/package.json @@ -1,7 +1,8 @@ { "scripts": { "cypress": "ETHEREAL_CACHE=false npx cypress open", - "a11y": "ETHEREAL_CACHE=false npx cypress run --spec 'cypress/e2e/admin/a11y/*'" + "a11y": "ETHEREAL_CACHE=false npx cypress run --spec 'cypress/e2e/admin/a11y/*'", + "ci": "ETHEREAL_CACHE=false npx cypress run --spec 'cypress/e2e/admin/ci.cy.js'" }, "dependencies": { "cypress-axe": "^1.4.0", From 9c64b3bdbe19ac7b1d41a06a43beb9ebc83d68ea Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 4 Oct 2024 13:59:40 +0000 Subject: [PATCH 24/38] chore: formatting --- app/config.py | 60 +++++++------------ app/utils.py | 2 +- .../e2e/admin/template/edit-template.cy.js | 12 +++- 3 files changed, 30 insertions(+), 44 deletions(-) diff --git a/app/config.py b/app/config.py index 23ebe2a6d0..16ed3e1816 100644 --- a/app/config.py +++ b/app/config.py @@ -25,8 +25,7 @@ class Config(object): ALLOW_DEBUG_ROUTE = env.bool("ALLOW_DEBUG_ROUTE", False) # List of allowed service IDs that are allowed to send HTML through their templates. - ALLOW_HTML_SERVICE_IDS: List[str] = [ - id.strip() for id in os.getenv("ALLOW_HTML_SERVICE_IDS", "").split(",")] + ALLOW_HTML_SERVICE_IDS: List[str] = [id.strip() for id in os.getenv("ALLOW_HTML_SERVICE_IDS", "").split(",")] ADMIN_BASE_URL = ( "https://" + os.environ.get("HEROKU_APP_NAME", "") + ".herokuapp.com" if os.environ.get("HEROKU_APP_NAME", "") != "" @@ -48,15 +47,12 @@ class Config(object): BULK_SEND_AWS_BUCKET = os.getenv("BULK_SEND_AWS_BUCKET") CHECK_PROXY_HEADER = False - CONTACT_EMAIL = os.environ.get( - "CONTACT_EMAIL", "assistance+notification@cds-snc.ca") - CRM_GITHUB_PERSONAL_ACCESS_TOKEN = os.getenv( - "CRM_GITHUB_PERSONAL_ACCESS_TOKEN") + CONTACT_EMAIL = os.environ.get("CONTACT_EMAIL", "assistance+notification@cds-snc.ca") + CRM_GITHUB_PERSONAL_ACCESS_TOKEN = os.getenv("CRM_GITHUB_PERSONAL_ACCESS_TOKEN") CRM_ORG_LIST_URL = os.getenv("CRM_ORG_LIST_URL") CSV_MAX_ROWS = env.int("CSV_MAX_ROWS", 50_000) CSV_MAX_ROWS_BULK_SEND = env.int("CSV_MAX_ROWS_BULK_SEND", 100_000) - CSV_UPLOAD_BUCKET_NAME = os.getenv( - "CSV_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-csv-upload") + CSV_UPLOAD_BUCKET_NAME = os.getenv("CSV_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-csv-upload") DANGEROUS_SALT = os.environ.get("DANGEROUS_SALT") DEBUG = False DEBUG_KEY = os.environ.get("DEBUG_KEY", "") @@ -71,30 +67,24 @@ class Config(object): "other": 25_000, } DEFAULT_LIVE_SERVICE_LIMIT = env.int("DEFAULT_LIVE_SERVICE_LIMIT", 10_000) - DEFAULT_LIVE_SMS_DAILY_LIMIT = env.int( - "DEFAULT_LIVE_SMS_DAILY_LIMIT", 1000) + DEFAULT_LIVE_SMS_DAILY_LIMIT = env.int("DEFAULT_LIVE_SMS_DAILY_LIMIT", 1000) DEFAULT_SERVICE_LIMIT = env.int("DEFAULT_SERVICE_LIMIT", 50) DEFAULT_SMS_DAILY_LIMIT = env.int("DEFAULT_SMS_DAILY_LIMIT", 50) - DOCUMENTATION_DOMAIN = os.getenv( - "DOCUMENTATION_DOMAIN", "documentation.notification.canada.ca") + DOCUMENTATION_DOMAIN = os.getenv("DOCUMENTATION_DOMAIN", "documentation.notification.canada.ca") EMAIL_2FA_EXPIRY_SECONDS = 1_800 # 30 Minutes EMAIL_EXPIRY_SECONDS = 3600 # 1 hour # for waffles: pull out the routes into a flat list of the form ['/home', '/accueil', '/why-gc-notify', ...] - EXTRA_ROUTES = [item for sublist in map( - lambda x: x.values(), GC_ARTICLES_ROUTES.values()) for item in sublist] + EXTRA_ROUTES = [item for sublist in map(lambda x: x.values(), GC_ARTICLES_ROUTES.values()) for item in sublist] # FEATURE FLAGS FF_SALESFORCE_CONTACT = env.bool("FF_SALESFORCE_CONTACT", True) FREE_YEARLY_EMAIL_LIMIT = env.int("FREE_YEARLY_EMAIL_LIMIT", 10_000_000) FREE_YEARLY_SMS_LIMIT = env.int("FREE_YEARLY_SMS_LIMIT", 25_000) - GC_ARTICLES_API = os.environ.get( - "GC_ARTICLES_API", "articles.alpha.canada.ca/notification-gc-notify") - GC_ARTICLES_API_AUTH_PASSWORD = os.environ.get( - "GC_ARTICLES_API_AUTH_PASSWORD") - GC_ARTICLES_API_AUTH_USERNAME = os.environ.get( - "GC_ARTICLES_API_AUTH_USERNAME") + GC_ARTICLES_API = os.environ.get("GC_ARTICLES_API", "articles.alpha.canada.ca/notification-gc-notify") + GC_ARTICLES_API_AUTH_PASSWORD = os.environ.get("GC_ARTICLES_API_AUTH_PASSWORD") + GC_ARTICLES_API_AUTH_USERNAME = os.environ.get("GC_ARTICLES_API_AUTH_USERNAME") GOOGLE_ANALYTICS_ID = os.getenv("GOOGLE_ANALYTICS_ID", "UA-102484926-14") GOOGLE_TAG_MANAGER_ID = os.getenv("GOOGLE_TAG_MANAGER_ID", "GTM-KRKRZQV") HC_EN_SERVICE_ID = os.getenv("HC_EN_SERVICE_ID") @@ -102,11 +92,9 @@ class Config(object): HIPB_ENABLED = True HTTP_PROTOCOL = "http" INVITATION_EXPIRY_SECONDS = 3_600 * 24 * 2 # 2 days - also set on api - IP_GEOLOCATE_SERVICE = os.environ.get( - "IP_GEOLOCATE_SERVICE", "").rstrip("/") + IP_GEOLOCATE_SERVICE = os.environ.get("IP_GEOLOCATE_SERVICE", "").rstrip("/") LANGUAGES = ["en", "fr"] - LOGO_UPLOAD_BUCKET_NAME = os.getenv( - "ASSET_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-asset-upload") + LOGO_UPLOAD_BUCKET_NAME = os.getenv("ASSET_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-asset-upload") MAX_FAILED_LOGIN_COUNT = 10 MOU_BUCKET_NAME = os.getenv("MOU_BUCKET_NAME", "") @@ -129,10 +117,8 @@ class Config(object): SCANFILES_URL = os.environ.get("SCANFILES_URL", "") SECRET_KEY = env.list("SECRET_KEY", []) - SECURITY_EMAIL = os.environ.get( - "SECURITY_EMAIL", "security+securite@cds-snc.ca") - SENDING_DOMAIN = os.environ.get( - "SENDING_DOMAIN", "notification.alpha.canada.ca") + SECURITY_EMAIL = os.environ.get("SECURITY_EMAIL", "security+securite@cds-snc.ca") + SENDING_DOMAIN = os.environ.get("SENDING_DOMAIN", "notification.alpha.canada.ca") SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_NAME = "notify_admin_session" SESSION_COOKIE_SAMESITE = "Lax" @@ -146,10 +132,8 @@ class Config(object): STATSD_PORT = 8_125 STATSD_PREFIX = os.getenv("STATSD_PREFIX") - TEMPLATE_PREVIEW_API_HOST = os.environ.get( - "TEMPLATE_PREVIEW_API_HOST", "http://localhost:6013") - TEMPLATE_PREVIEW_API_KEY = os.environ.get( - "TEMPLATE_PREVIEW_API_KEY", "my-secret-key") + TEMPLATE_PREVIEW_API_HOST = os.environ.get("TEMPLATE_PREVIEW_API_HOST", "http://localhost:6013") + TEMPLATE_PREVIEW_API_KEY = os.environ.get("TEMPLATE_PREVIEW_API_KEY", "my-secret-key") WAF_SECRET = os.environ.get("WAF_SECRET", "waf-secret") WTF_CSRF_ENABLED = True WTF_CSRF_TIME_LIMIT = None @@ -160,8 +144,7 @@ class Config(object): NOTIFY_USER_ID = "6af522d0-2915-4e52-83a3-3690455a5fe6" NOTIFY_SERVICE_ID = "d6aa2c68-a2d9-4437-ab19-3ae8eb202553" - NO_BRANDING_ID = os.environ.get( - "NO_BRANDING_ID", "0af93cf1-2c49-485f-878f-f3e662e651ef") + NO_BRANDING_ID = os.environ.get("NO_BRANDING_ID", "0af93cf1-2c49-485f-878f-f3e662e651ef") @classmethod def get_sensitive_config(cls) -> list[str]: @@ -189,8 +172,7 @@ def get_safe_config(cls) -> dict[str, Any]: class Development(Config): - ADMIN_CLIENT_SECRET = os.environ.get( - "ADMIN_CLIENT_SECRET", "dev-notify-secret-key") + ADMIN_CLIENT_SECRET = os.environ.get("ADMIN_CLIENT_SECRET", "dev-notify-secret-key") ANTIVIRUS_API_HOST = "http://localhost:6016" ANTIVIRUS_API_KEY = "test-key" API_HOST_NAME = os.environ.get("API_HOST_NAME", "http://localhost:6011") @@ -207,8 +189,7 @@ class Development(Config): class Test(Development): - ADMIN_CLIENT_SECRET = os.environ.get( - "ADMIN_CLIENT_SECRET", "dev-notify-secret-key") + ADMIN_CLIENT_SECRET = os.environ.get("ADMIN_CLIENT_SECRET", "dev-notify-secret-key") ANTIVIRUS_API_HOST = "https://test-antivirus" ANTIVIRUS_API_KEY = "test-antivirus-secret" API_HOST_NAME = os.environ.get("API_HOST_NAME", "http://localhost:6011") @@ -239,8 +220,7 @@ class Test(Development): class ProductionFF(Config): - ADMIN_CLIENT_SECRET = os.environ.get( - "ADMIN_CLIENT_SECRET", "dev-notify-secret-key") + ADMIN_CLIENT_SECRET = os.environ.get("ADMIN_CLIENT_SECRET", "dev-notify-secret-key") ANTIVIRUS_API_HOST = "https://test-antivirus" ANTIVIRUS_API_KEY = "test-antivirus-secret" API_HOST_NAME = os.environ.get("API_HOST_NAME", "http://localhost:6011") diff --git a/app/utils.py b/app/utils.py index f98a34f6ea..e9de092796 100644 --- a/app/utils.py +++ b/app/utils.py @@ -93,7 +93,7 @@ def from_lambda_api(line): return isinstance(line, dict) -@cache.memoize(timeout=12*60*60) +@cache.memoize(timeout=12 * 60 * 60) def get_latest_stats(lang, filter_heartbeats=None): results = service_api_client.get_stats_by_month(filter_heartbeats=filter_heartbeats)["data"] diff --git a/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js b/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js index 4b4b5ea1a4..18be1f4f9e 100644 --- a/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js +++ b/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js @@ -20,11 +20,14 @@ describe("Edit template", () => { cy.visit(`/services/${config.Services.Cypress}/templates`); // set template priority to use TC - Page.SelectTemplateById(config.Services.Cypress, config.Templates.SMOKE_TEST_SMS); + Page.SelectTemplateById( + config.Services.Cypress, + config.Templates.SMOKE_TEST_SMS, + ); Page.EditCurrentTemplate(); Page.SetTemplatePriority("bulk"); Page.SaveTemplate(); - + // use api to check that it was set Admin.GetTemplate({ templateId: config.Templates.SMOKE_TEST_SMS, @@ -117,7 +120,10 @@ describe("Edit template", () => { cy.visit(`/services/${config.Services.Cypress}/templates`); // set template priority to use TC - Page.SelectTemplateById(config.Services.Cypress, config.Templates.SMOKE_TEST_EMAIL); + Page.SelectTemplateById( + config.Services.Cypress, + config.Templates.SMOKE_TEST_EMAIL, + ); Page.EditCurrentTemplate(); Page.Components.TemplateSubject().type("a"); Page.SetTemplatePriority("bulk"); From 63a1b9239e1c1f9c3c83b6bbb8e87bed0bd30e47 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 8 Nov 2024 18:22:20 +0000 Subject: [PATCH 25/38] fix(cypress): update tests to use updated, simplified `cy.login()` command --- tests_cypress/cypress/e2e/admin/service-settings.cy.js | 2 +- tests_cypress/cypress/e2e/admin/template/text-direction.cy.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests_cypress/cypress/e2e/admin/service-settings.cy.js b/tests_cypress/cypress/e2e/admin/service-settings.cy.js index 1df11704bd..e9b658250f 100644 --- a/tests_cypress/cypress/e2e/admin/service-settings.cy.js +++ b/tests_cypress/cypress/e2e/admin/service-settings.cy.js @@ -30,7 +30,7 @@ describe("Platform Admin Service Settings", () => { beforeEach(() => { // stop the recurring dashboard fetch requests cy.intercept("GET", "**/dashboard.json", {}); - cy.login(Cypress.env("NOTIFY_ADMIN_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit( config.Hostnames.Admin + `/services/${config.Services.Cypress}/service-settings`, diff --git a/tests_cypress/cypress/e2e/admin/template/text-direction.cy.js b/tests_cypress/cypress/e2e/admin/template/text-direction.cy.js index 85ffecd49b..c407bedb9e 100644 --- a/tests_cypress/cypress/e2e/admin/template/text-direction.cy.js +++ b/tests_cypress/cypress/e2e/admin/template/text-direction.cy.js @@ -15,7 +15,7 @@ const templates = { describe("Template text direction", () => { beforeEach(() => { - cy.login(Cypress.env("NOTIFY_USER"), Cypress.env("NOTIFY_PASSWORD")); + cy.login(); cy.visit(`/services/${config.Services.Cypress}/templates`); }); From d3f2d370dc10143eca98a4c631706d1c72f19bad Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 8 Nov 2024 18:42:06 +0000 Subject: [PATCH 26/38] chore: formatting --- tests_cypress/cypress/e2e/admin/service-settings.cy.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests_cypress/cypress/e2e/admin/service-settings.cy.js b/tests_cypress/cypress/e2e/admin/service-settings.cy.js index e9b658250f..bd75c7c501 100644 --- a/tests_cypress/cypress/e2e/admin/service-settings.cy.js +++ b/tests_cypress/cypress/e2e/admin/service-settings.cy.js @@ -12,7 +12,7 @@ describe("Service Settings", () => { cy.visit( config.Hostnames.Admin + - `/services/${config.Services.Cypress}/service-settings`, + `/services/${config.Services.Cypress}/service-settings`, ); }); @@ -33,7 +33,7 @@ describe("Platform Admin Service Settings", () => { cy.login(); cy.visit( config.Hostnames.Admin + - `/services/${config.Services.Cypress}/service-settings`, + `/services/${config.Services.Cypress}/service-settings`, ); }); From becd2ab3f095a4b00f312f58f7f3642db8418b63 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 8 Nov 2024 19:14:37 +0000 Subject: [PATCH 27/38] chore: update config to use staging --- tests_cypress/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests_cypress/config.js b/tests_cypress/config.js index f37922bde2..1fc49aa0fb 100644 --- a/tests_cypress/config.js +++ b/tests_cypress/config.js @@ -33,6 +33,6 @@ const config = { }; // choose which config to use here -const ConfigToUse = { ...config.COMMON, ...config.LOCAL }; +const ConfigToUse = { ...config.COMMON, ...config.STAGING }; module.exports = ConfigToUse; From bbe2bdbbc2f6728dcc266c319cf8bd6b56519202 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 15 Nov 2024 10:46:25 -0400 Subject: [PATCH 28/38] fix(remaining_messages_summary test): add assert to ensure test waits for language to change --- .../e2e/admin/components/remaining_messages_summary.cy.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js b/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js index 13095a7bba..bd17a76d0a 100644 --- a/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js +++ b/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js @@ -53,7 +53,7 @@ describe("Remaining Messages Summary Component", () => { }); }); - describe("Thousands separator", () => { + describe.only("Thousands separator", () => { it("shows thousands separator in EN for today’s remaining", () => { RMS.Below() .find('*[data-testid="rms"]') @@ -64,6 +64,8 @@ describe("Remaining Messages Summary Component", () => { it("shows thousands separator in FR for today’s remaining", () => { cy.get("#header-lang").click(); + // assert html node has lang attribute = fr + cy.get("html").should("have.attr", "lang", "fr"); cy.visit(PageURL); RMS.Below() .find('*[data-testid="rms"]') @@ -82,6 +84,7 @@ describe("Remaining Messages Summary Component", () => { it("shows thousands separator in FR for the year’s remaining", () => { cy.get("#header-lang").click(); + cy.get("html").should("have.attr", "lang", "fr"); cy.visit(PageURL); RMS.Below() .find('*[data-testid="rms"]') From c314ea89df189e854d1343696bd8a026278626d9 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 15 Nov 2024 10:47:05 -0400 Subject: [PATCH 29/38] chore: remove debug code --- .../e2e/admin/components/remaining_messages_summary.cy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js b/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js index bd17a76d0a..eef0de63af 100644 --- a/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js +++ b/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js @@ -53,7 +53,7 @@ describe("Remaining Messages Summary Component", () => { }); }); - describe.only("Thousands separator", () => { + describe("Thousands separator", () => { it("shows thousands separator in EN for today’s remaining", () => { RMS.Below() .find('*[data-testid="rms"]') From 0183f84bc800b51e34a9009ca8f24c8599a9dac1 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 15 Nov 2024 11:07:34 -0400 Subject: [PATCH 30/38] fix(template_filters test): make sure the scenario ends in no results --- tests_cypress/cypress/e2e/admin/template-filters.cy.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests_cypress/cypress/e2e/admin/template-filters.cy.js b/tests_cypress/cypress/e2e/admin/template-filters.cy.js index 50a4a446c6..d36204e34d 100644 --- a/tests_cypress/cypress/e2e/admin/template-filters.cy.js +++ b/tests_cypress/cypress/e2e/admin/template-filters.cy.js @@ -14,8 +14,8 @@ const categories = { }; const catEmpty = { - en: "Authentication", - fr: "Authentification", + en: "Test", + fr: "Test", }; describe("Template filters", () => { @@ -166,7 +166,7 @@ describe("Template filters", () => { Page.Components.EmptyState().should("not.be.visible"); Page.ToggleFilters(); - Page.ApplyTypeFilter(types[lang][0]); + Page.ApplyTypeFilter(types[lang][1]); Page.ApplyCategoryFilter(catEmpty[lang]); // Empty state should be visible From 213c122b5ac3a5f2540355e1d7f5360d4a7cc50c Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 15 Nov 2024 15:15:06 +0000 Subject: [PATCH 31/38] fix(cypress login): use cypress auth to get new user --- tests_cypress/cypress/support/commands.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests_cypress/cypress/support/commands.js b/tests_cypress/cypress/support/commands.js index 7fdf72b89c..bb5d67386f 100644 --- a/tests_cypress/cypress/support/commands.js +++ b/tests_cypress/cypress/support/commands.js @@ -99,7 +99,7 @@ Cypress.Commands.add('getByTestId', (selector, ...args) => { }); Cypress.Commands.add('login', (agreeToTerms = true) => { - cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET') }).then((acct) => { + cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('CYPRESS_AUTH_USER_NAME'), secret: Cypress.env('CYPRESS_AUTH_CLIENT_SECRET') }).then((acct) => { cy.session([acct.regular.email_address, agreeToTerms], () => { LoginPage.Login(acct.regular.email_address, Cypress.env('NOTIFY_PASSWORD'), agreeToTerms); }); @@ -108,9 +108,9 @@ Cypress.Commands.add('login', (agreeToTerms = true) => { Cypress.Commands.add('loginAsPlatformAdmin', (agreeToTerms = true) => { - cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET') }).then((acct) => { + cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('CYPRESS_AUTH_USER_NAME'), secret: Cypress.env('CYPRESS_AUTH_CLIENT_SECRET') }).then((acct) => { cy.session([acct.admin.email_address, agreeToTerms], () => { LoginPage.Login(acct.admin.email_address, Cypress.env('NOTIFY_PASSWORD'), agreeToTerms); }); }); -}); \ No newline at end of file +}); From 47a192ba3112bd2e187af6adda8540e904bdd5c7 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 15 Nov 2024 12:58:57 -0400 Subject: [PATCH 32/38] fix failing tests --- .../e2e/admin/components/remaining_messages_summary.cy.js | 1 - tests_cypress/cypress/e2e/admin/template/edit-template.cy.js | 4 +--- tests_cypress/cypress/support/commands.js | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js b/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js index eef0de63af..ae9d435d26 100644 --- a/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js +++ b/tests_cypress/cypress/e2e/admin/components/remaining_messages_summary.cy.js @@ -64,7 +64,6 @@ describe("Remaining Messages Summary Component", () => { it("shows thousands separator in FR for today’s remaining", () => { cy.get("#header-lang").click(); - // assert html node has lang attribute = fr cy.get("html").should("have.attr", "lang", "fr"); cy.visit(PageURL); RMS.Below() diff --git a/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js b/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js index 18be1f4f9e..8609ffc8b6 100644 --- a/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js +++ b/tests_cypress/cypress/e2e/admin/template/edit-template.cy.js @@ -113,7 +113,6 @@ describe("Edit template", () => { context("FF ON", () => { // Override the process_type -> new process type should be saved for an existing template it("Should allow platform admin to override process type", () => { - cy.log("CONMFIG", config); // Admin user 1. // login as admin cy.loginAsPlatformAdmin(); @@ -131,10 +130,9 @@ describe("Edit template", () => { // use api to check that it was set Admin.GetTemplate({ - templateId: config.Templates.SMOKE_TEST_SMS, + templateId: config.Templates.SMOKE_TEST_EMAIL, serviceId: config.Services.Cypress, }).then((response) => { - console.log("response", response); expect(response.body.data.process_type_column).to.equal("bulk"); }); }); diff --git a/tests_cypress/cypress/support/commands.js b/tests_cypress/cypress/support/commands.js index 7fdf72b89c..5ba4c760e0 100644 --- a/tests_cypress/cypress/support/commands.js +++ b/tests_cypress/cypress/support/commands.js @@ -99,7 +99,7 @@ Cypress.Commands.add('getByTestId', (selector, ...args) => { }); Cypress.Commands.add('login', (agreeToTerms = true) => { - cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET') }).then((acct) => { + cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('CYPRESS_AUTH_USER_NAME'), secret: Cypress.env('CYPRESS_AUTH_CLIENT_SECRET') }).then((acct) => { cy.session([acct.regular.email_address, agreeToTerms], () => { LoginPage.Login(acct.regular.email_address, Cypress.env('NOTIFY_PASSWORD'), agreeToTerms); }); @@ -108,7 +108,7 @@ Cypress.Commands.add('login', (agreeToTerms = true) => { Cypress.Commands.add('loginAsPlatformAdmin', (agreeToTerms = true) => { - cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('ADMIN_USERNAME'), secret: Cypress.env('ADMIN_SECRET') }).then((acct) => { + cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('CYPRESS_AUTH_USER_NAME'), secret: Cypress.env('CYPRESS_AUTH_CLIENT_SECRET') }).then((acct) => { cy.session([acct.admin.email_address, agreeToTerms], () => { LoginPage.Login(acct.admin.email_address, Cypress.env('NOTIFY_PASSWORD'), agreeToTerms); }); From 1548f4986aebbcfd62c178cc8219957b2a9cf029 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 15 Nov 2024 14:02:20 -0400 Subject: [PATCH 33/38] fix(cypress config): add back retries --- tests_cypress/cypress.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests_cypress/cypress.config.js b/tests_cypress/cypress.config.js index 1221430303..74dcbeadfd 100644 --- a/tests_cypress/cypress.config.js +++ b/tests_cypress/cypress.config.js @@ -65,6 +65,6 @@ module.exports = defineConfig({ viewportWidth: 1280, viewportHeight: 850, testIsolation: true, - // retries: 3 + retries: 3 }, }); From 5f53f67da3ca3f7328e7478e78f8859cc2278e83 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 15 Nov 2024 18:23:06 +0000 Subject: [PATCH 34/38] please [review] me From 62a2536844a9f63ed1f77d53ff9817857f8927a8 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 15 Nov 2024 18:31:18 +0000 Subject: [PATCH 35/38] fix: change secret name for new user password so this wont conflict with existing PRs --- tests_cypress/cypress/support/commands.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests_cypress/cypress/support/commands.js b/tests_cypress/cypress/support/commands.js index bb5d67386f..912ec680a4 100644 --- a/tests_cypress/cypress/support/commands.js +++ b/tests_cypress/cypress/support/commands.js @@ -101,7 +101,7 @@ Cypress.Commands.add('getByTestId', (selector, ...args) => { Cypress.Commands.add('login', (agreeToTerms = true) => { cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('CYPRESS_AUTH_USER_NAME'), secret: Cypress.env('CYPRESS_AUTH_CLIENT_SECRET') }).then((acct) => { cy.session([acct.regular.email_address, agreeToTerms], () => { - LoginPage.Login(acct.regular.email_address, Cypress.env('NOTIFY_PASSWORD'), agreeToTerms); + LoginPage.Login(acct.regular.email_address, Cypress.env('CYPRESS_USER_PASSWORD'), agreeToTerms); }); }); }); @@ -110,7 +110,7 @@ Cypress.Commands.add('login', (agreeToTerms = true) => { Cypress.Commands.add('loginAsPlatformAdmin', (agreeToTerms = true) => { cy.task('createAccount', { baseUrl: config.Hostnames.API, username: Cypress.env('CYPRESS_AUTH_USER_NAME'), secret: Cypress.env('CYPRESS_AUTH_CLIENT_SECRET') }).then((acct) => { cy.session([acct.admin.email_address, agreeToTerms], () => { - LoginPage.Login(acct.admin.email_address, Cypress.env('NOTIFY_PASSWORD'), agreeToTerms); + LoginPage.Login(acct.admin.email_address, Cypress.env('CYPRESS_USER_PASSWORD'), agreeToTerms); }); }); }); From c10d268f497533a5b790b753ab972ed522d41dd8 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 15 Nov 2024 18:42:57 +0000 Subject: [PATCH 36/38] chore: README updates --- tests_cypress/README.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tests_cypress/README.md b/tests_cypress/README.md index f150ad9ff2..4a408a7ce7 100644 --- a/tests_cypress/README.md +++ b/tests_cypress/README.md @@ -28,17 +28,23 @@ npx cypress install - `config.js`: this file contains non-sensitive items like template ids and hostnames that you'll need to run the tests ### `cypress.env.json` contents -| key | description | -| --------------- | ----------------------------------------------- | -| ADMIN_SECRET | Secret admin uses to authenticate against API | -| ADMIN_USERNAME | Username admin uses to authenticate against API | -| NOTIFY_USER | Notify user used by the tests | -| NOTIFY_PASSWORD | Password of NOTIFY_USER | -| IMAP_PASSWORD | IMAP password of gmail account for NOTIFY_USER | +| key | description | +| -------------------------- | ----------------------------------------------- | +| ADMIN_SECRET | Secret admin uses to authenticate against API | +| ADMIN_USERNAME | Username admin uses to authenticate against API | +| NOTIFY_USER | Notify user used by the tests | +| NOTIFY_PASSWORD | Password of NOTIFY_USER (deprecated) | +| IMAP_PASSWORD | IMAP password of gmail account for NOTIFY_USER | +| CYPRESS_AUTH_USER_NAME | Username for the Cypress auth client | +| CYPRESS_AUTH_CLIENT_SECRET | Secret for the Cypress auth client | +| NOTIFY_USER | Actual notify user CDS email account | +| NOTIFY_PASSWORD | Password of NOTIFY_USER (deprecated) | +| CYPRESS_USER_PASSWORD | Password for the Cypress user | +| IMAP_PASSWORD | IMAP password of gmail account for NOTIFY_USER | ### Target environment 🎯 The tests are configured to run against the staging environment by default. To run the tests against your local environment, you'll need to create a local service and API keys and store these values in your config. You will also need to update the `ConfigToUse` variable in `config.js` file: ```js -const ConfigToUse = config.LOCAL; +const ConfigToUse = { ...config.COMMON, ...config.LOCAL }; ``` From 413a8707b9438c7974ffa2c40a5362a608e6ca20 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 15 Nov 2024 19:50:35 +0000 Subject: [PATCH 37/38] chore: remove unused import --- tests_cypress/cypress/support/commands.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests_cypress/cypress/support/commands.js b/tests_cypress/cypress/support/commands.js index 912ec680a4..ec7683582c 100644 --- a/tests_cypress/cypress/support/commands.js +++ b/tests_cypress/cypress/support/commands.js @@ -3,7 +3,6 @@ import "cypress-real-events"; import config from "../../config"; import LoginPage from "../Notify/Admin/Pages/LoginPage"; -import { Admin } from "../Notify/NotifyAPI"; // keep track of what we test so we dont test the same thing twice let links_checked = []; From 5aaa300dae14d9a1375c145275d25c83e5dd91f8 Mon Sep 17 00:00:00 2001 From: Andrew Leith Date: Fri, 15 Nov 2024 19:57:49 +0000 Subject: [PATCH 38/38] chore: removed comments --- .../cypress/plugins/email-account.js | 30 +++++-------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/tests_cypress/cypress/plugins/email-account.js b/tests_cypress/cypress/plugins/email-account.js index 7848054ea8..0a2ec46b1e 100644 --- a/tests_cypress/cypress/plugins/email-account.js +++ b/tests_cypress/cypress/plugins/email-account.js @@ -10,7 +10,7 @@ const emailAccount = async () => { const emailConfig = { imap: { - user: env.NOTIFY_USER, + user: env.NOTIFY_USER, password: env.IMAP_PASSWORD, host: 'imap.gmail.com', port: 993, @@ -28,8 +28,6 @@ const emailAccount = async () => { * for the Ethereal email account */ async deleteAllEmails() { - // console.debug('Purging the inbox...') - try { const connection = await imaps.connect(emailConfig) @@ -42,12 +40,10 @@ const emailAccount = async () => { const messages = await connection.search(searchCriteria, fetchOptions) if (!messages.length) { - // console.log('Cannot find any emails') // and close the connection to avoid it hanging connection.end() return null } else { - // console.log('There are %d messages, deleting them...', messages.length) // delete all messages const uidsToDelete = messages .filter(message => { @@ -75,11 +71,11 @@ const emailAccount = async () => { * Utility method for getting the last email * for the Ethereal email account */ - async getLastEmail(emailAddress) { + async getLastEmail(emailAddress) { let connection; try { connection = await imaps.connect(emailConfig); - + // grab up to 50 emails from the inbox await connection.openBox('INBOX'); const searchCriteria = ['UNSEEN']; @@ -88,7 +84,7 @@ const emailAccount = async () => { struct: true, }; const messages = await connection.search(searchCriteria, fetchOptions); - + if (!messages.length) { return null; } else { @@ -107,7 +103,7 @@ const emailAccount = async () => { }; } } - + try { if (uidsToDelete.length > 0) { await connection.deleteMessage(uidsToDelete); @@ -116,7 +112,7 @@ const emailAccount = async () => { } catch (e) { console.error('delete error', uidsToDelete, e); } - + return latestMail; } } catch (e) { @@ -131,7 +127,7 @@ const emailAccount = async () => { async fetchEmail(acct) { const _config = { imap: { - user: acct.user, + user: acct.user, password: acct.pass, host: "imap.ethereal.email", //'imap.gmail.com', port: 993, @@ -156,20 +152,8 @@ const emailAccount = async () => { connection.end() if (!messages.length) { - // console.log('Cannot find any emails, retrying...') return null } else { - // console.log('There are %d messages', messages.length) - // messages.forEach(function (item) { - // var all = _.find(item.parts, { "which": "" }) - // var id = item.attributes.uid; - // var idHeader = "Imap-Id: "+id+"\r\n"; - // simpleParser(idHeader+all.body, (err, mail) => { - // // access to the whole mail object - // console.log(mail.subject) - // console.log(mail.html) - // }); - // }); // grab the last email const mail = await simpleParser(