Last active
July 9, 2022 15:45
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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