Skip to content

Instantly share code, notes, and snippets.

@alfredlucero
Last active July 9, 2022 15:45
Show Gist options
  • Save alfredlucero/b583491c21fa530a3a7c999b163fe887 to your computer and use it in GitHub Desktop.
Save alfredlucero/b583491c21fa530a3a7c999b163fe887 to your computer and use it in GitHub Desktop.
Cypress Tips/Tricks - Using cheerio to parse email body contents, make cy.request() to links, follow redirect back to web app
// In some page_object.ts
// For this scenario, we have a Cypress test that triggers a download email to be sent to the user's inbox after performing
// some UI steps on the page i.e. clicking a button on the page to export data to a CSV for us to download
// We need to follow the download link in the email back to the web app we own and control to continue the test
redirectToCSVDownloadPageFromEmail({
user,
pass,
searchString,
}: {
user: string;
pass: string;
searchString: string;
}) {
// First, wait for export email to arrive in squirrelmail inbox
const squirrelmailTimeoutInMs = 120000;
const checkIntervalInMs = 15000;
// This wraps our cy.task("awaitEmailInSquirrelmailInbox") function call
return this.awaitEmailInSquirrelmailInbox({
user,
pass,
searchString,
timeoutInMs: squirrelmailTimeoutInMs,
checkIntervalInMs,
}).then(() =>
// We find the matching email and extract its email body string
cy
.task('squirrelmailSearchBySubject', {
user,
pass,
searchString,
// CSV downloads are valid for up to 3 days
// We'll check since two days ago to be safely within 0-3 days range
sinceNumDaysAgo: 2,
})
.then((rawEmailBody) => {
if (rawEmailBody) {
return this.parseDownloadLink(rawEmailBody);
}
cy.log(
'Failed to retrieve latest matching email by subject due to some error'
);
throw new Error('Test failed to get to CSV download page');
})
// Make an HTTP request to the download link that we find in the email body
.then((downloadLink) => this.requestCSVDownload(downloadLink))
// Extract out the 302 redirect path for us to visit back to our web app
.then((results) => this.redirectToCSVDownloadPage(results))
);
}
parseDownloadLink(rawEmailBody: string) {
// Parse out the HTML part of the email body for us to look through
let flattenedMIMEBody = rawEmailBody.replace(/(=\r\n)/g, '');
flattenedMIMEBody = flattenedMIMEBody.replace(/(=\n)/g, '');
flattenedMIMEBody = flattenedMIMEBody.replace(/(=3D)/g, '=');
const startOfHTML = flattenedMIMEBody.indexOf('<html>');
const endOfHTML = flattenedMIMEBody.indexOf('</html>') + '</html>'.length;
const emailHTML = flattenedMIMEBody.slice(startOfHTML, endOfHTML);
// Using cheerio, we can load up the HTML string of the email body
// and then easily filter through the elements for the Download link with jQuery-like functions
const $ = cheerio.load(emailHTML);
const downloadTag = $('a').filter(
(i, aTag) => $(aTag).text() === 'Download'
);
const downloadLink = downloadTag.attr('href') || '';
return downloadLink;
}
// We make an HTTP request to the link that looks like "...sendgrid.net..." or "brandedlink.com"
requestCSVDownload(downloadLink: string) {
return cy.request(downloadLink);
}
// After making the HTTP request to the download link, we extract out the redirect path for
// us to cy.visit() back to our web app
redirectToCSVDownloadPage(results: any) {
const redirect = results.redirects[0];
// String looks like 302: https://staging.app.com/download/path
const [redirectStatus, redirectRoute] = redirect.split(' ');
// We extract out the /download/path plus any query params after it
const redirectURL = new URL(redirectRoute);
const csvDownloadPath = `${redirectURL.pathname}${redirectURL.search}`;
// cy.visit(/download/path?token=<token>) to go back to our web app on the same superdomain
return cy.visit(csvDownloadPath);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment