How to integrate Ethereal email service with Cypress 10

449 Views Asked by At

I am trying to integrate Ethereal email service with Cypress for Email testing. I followed this example project https://github.com/bahmutov/cypress-ethereal-email-example This project is written for Cypress version < 10. I am trying to make it work for Cypress 10.3.1. Followed the below steps:

  1. Created email-account.js inside cypress/support directory
  2. Tried copying cypress/plugins/index.js inside cypress.config.js

Content of cypress.config.js

const { defineConfig } = require('cypress')
const fs = require('fs');
const { isFileExist } = require('cy-verify-downloads');
const xlsx = require('node-xlsx').default;
const path = require('path');
const exec = require('child_process');
const makeEmailAccount = require('./cypress/support/email-account')
module.exports = defineConfig({
e2e: {
 setupNodeEvents (on, config) {
 const emailAccount =  makeEmailAccount()
 on('task', {
   getUserEmail() {
     const emailAccount =  makeEmailAccount()
     console.log(emailAccount)
     return new Promise((resolve) => {
     // tasks should not resolve with undefined
     console.log(emailAccount)
     return resolve(emailAccount.email)
   })
 },

 getLastEmail() {
   return emailAccount.getLastEmail()
 },
})
})

I am getting the below error on trying to test emails:

task getUserEmail
CypressError
cy.task('getUserEmail') failed with the following error:

The task 'getUserEmail' returned undefined. You must return a value, null, or a promise that resolves to a value or null to indicate that the task was handled.

The task handler was:

getUserEmail() {
  return new Promise((resolve) => {
  // tasks should not resolve with undefined
  return resolve(emailAccount.email)
  })
}

Fix this in your setupNodeEvents method here:
/Users/ashoknegi/Sites/renesas-d9/cypress.config.js

Can someone help with this issue? I think the issue is with Asynchronous function calls in the config file. I checked asynchronous tasks and came across this link and tried to implement it the same way. https://docs.cypress.io/api/commands/task#Return-a-Promise-from-an-asynchronous-task Has anyone integrated Ethereal email service with Cypress 10? Any help much appreciated.

1

There are 1 best solutions below

0
On

To translate Gleb's v9 /plugins/index.js to v10 cypress.config.js, you need setupNodeEvents() to be async and await the result of makeEmeialAccount().

Cypress v9

module.exports = async (on) => {
  const emailAccount = await makeEmailAccount()

  on('task', {
    getUserEmail() {
      return emailAccount.email
    },

    getLastEmail() {
      return emailAccount.getLastEmail()
    },
  })
}

Cypress v10

e2e: {
 setupNodeEvents:  async (on, config) => {
   const emailAccount = await makeEmailAccount()

   on('task', {
     getUserEmail() {
       return emailAccount.email
     },

     getLastEmail() {
       return emailAccount.getLastEmail()
     },
   })
 },

Using Promise.resolve() is technically a legit way to do it, but since you're not awaiting you need to use the .then(emailAccount => resolve(emailAccount)) pattern.

e2e: {
  setupNodeEvents (on, config) {

    on('task', {
      getUserEmail() {
        return new Promise((resolve) => {
          makeEmailAccount().then(emailAccount => {
            resolve(emailAccount.email)
          })
        })
      }
    }
  }
},

However, Promise.resolve() is less useful than the async/await approach, because to add getLastEmail() or to call getUserEmail() task twice in the tests you are effectively making a different email each time you call.