Using Cypress for test automation, I'm trying to find a solution on how to scrape an email body, get the link out of it, store it in a variable and then visit the link via cy.visit().
/// <reference types="Cypress" />
const sender = "sender@companyemail.com";
const companyEmail = "company@company.com"
const emailSubject = "[Action required] Activate your 14-day Dataddo trial";
describe("Sign-Up Email assertion and visit confirmation link", () => {
it("Sign-Up and Look for an email with specific subject and link in email body", function () {
cy.task("gmail:get-messages", {
options: {
from: sender,
to: companyEmail,
subject: emailSubject,
include_body: true
}
}).then(emails => {
assert.isNotNull(
emails,
"Expected to find at least one email, but none were found!"
);
cy.log("Email has been found successfully")
assert.isAtLeast(
emails.length,
1,
"Expected to find at least one email, but none were found!"
);
cy.log(`Email length is: ${emails.length}`)
cy.log(`Email Recipient is: ${companyEmail}`)
const body = emails[0].body.html; // returns email body (see the mock-up below)
/*
TODO
- Parse email body, get the confirmation link out of it
- Store the link it a variable
- Visit the link via cy.visit
- Note that tokenid is going to be different with every run
*/
})
})
})
Mock-up of the expected email body is available below.
<html>
<head>
</head>
<body>
<p>This is SignUp Email with confirmation link</p>
<p>
<a href = "http://www.company.com/ls/click?upn=tokenid-11111-22222-333333-444444-555555-xxxxxx"><a>
</p>
</body>
</html>
Thank you for your help.
You could use a json file to store the link and then just visit it in the next test by retrieving it from the json.
cy.readFile(json).then((obj) => {
cy.get('a').invoke('attr', 'href').then((href) => {
obj.activationLink = href
cy.writeFile(json, obj)
})
})
it('visits the link', function() {
cy.readFile(json).then((obj) => {
cy.visit(obj.activationLink)
})
})
Set the string in body variable in a <template>.
Use Cypress.$() (i.e jQuery) commands to query it.
const template = document.createElement('template')
template.innerHTML = body.trim()
const link = Cypress.$(template.content)
.find('a[href]')
.attr('href')
cy.visit(link)
//or
cy.wrap(link).as('link') // store to a variable
Note you can't use Cypress commands on <template> as it's not attached to the current DOM.
This is how I have solved this problem (using gmail-tester as I see You have used as well / although any api which returns body of the email will do the trick)
Once the body is returned - use cy.document() method to 'write' the email in to cypress runner browser and then just quarry for the link the cypress way and paste it into cy.visit() if needed.
If you need to store it into a variable just declare it before the test and use it rather than accessing the step presented below in cy.visit() - just remember that by doing so your test will rely on each other.
In the example below from the array of emails, I am taking the first object then using its body param and HTML nested within it.
// let link
[...]
.then((emails) => {
const body = emails[0].body.html;
cy.document({ log: false }).invoke({ log: false }, 'write', body);
})
.then(() => {
cy.get('a')
.contains('Verify My Email')
.invoke('attr', 'href')
.then((href) => {
cy.visit(href);
// link = href
});
})