diff --git a/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Email_settings_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Email_settings_Spec.ts index d3fdc9df0407..f6829276f99e 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Email_settings_Spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Email_settings_Spec.ts @@ -202,6 +202,7 @@ describe( timeout: TIMEOUT, targetSubject: resetPassSubject, targetEmail: emailOne, + requireHtml: true, }) .then((email) => { if (email) { @@ -282,6 +283,7 @@ describe( timeout: TIMEOUT, targetSubject: inviteEmailSubject, targetEmail: emailTwo, + requireHtml: true, }) .then((email) => { if (email) { @@ -362,6 +364,7 @@ describe( timeout: TIMEOUT, targetSubject: inviteEmailSubject, targetEmail: emailThree, + requireHtml: true, }) .then((email) => { if (email) { @@ -464,6 +467,7 @@ describe( timeout: TIMEOUT, targetSubject: inviteEmailSubject, targetEmail: emailFour, + requireHtml: true, }) .then((email) => { if (email) { diff --git a/app/client/cypress/support/Pages/AggregateHelper.ts b/app/client/cypress/support/Pages/AggregateHelper.ts index eaa946624b31..589ca68a1c56 100644 --- a/app/client/cypress/support/Pages/AggregateHelper.ts +++ b/app/client/cypress/support/Pages/AggregateHelper.ts @@ -2025,6 +2025,7 @@ export class AggregateHelper { public waitForEmail({ pollInterval, + requireHtml = false, targetEmail, targetSubject, timeout, @@ -2033,6 +2034,7 @@ export class AggregateHelper { timeout: number; targetSubject: string; targetEmail?: string; + requireHtml?: boolean; }): Cypress.Chainable { const endTime = Date.now() + timeout; let latestEmail: any = null; @@ -2058,6 +2060,7 @@ export class AggregateHelper { from: string; }; text: string; + html?: string; }> = res.body; const matchingEmails = emails.filter((email) => { @@ -2066,14 +2069,21 @@ export class AggregateHelper { .toLowerCase() .includes(targetSubject.trim().toLowerCase()); - if (targetEmail) { - const emailTo = email.headers.to.trim().toLowerCase(); - return ( - subjectMatch && emailTo === targetEmail.trim().toLowerCase() - ); - } - - return subjectMatch; + const recipientMatch = targetEmail + ? email.headers.to.trim().toLowerCase() === + targetEmail.trim().toLowerCase() + : true; + + // When the caller needs the HTML body, treat a matched email whose + // body has not been populated yet as "not yet delivered" and keep + // polling, rather than returning it and letting the caller throw on + // email.html. Maildev can surface an email's metadata before its + // HTML part is parsed, especially under load. + const htmlReady = + !requireHtml || + (typeof email.html === "string" && email.html.length > 0); + + return subjectMatch && recipientMatch && htmlReady; }); if (matchingEmails.length > 0) {