You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ethereal邮件服务集成Cypress 10遇报错,求解决方案

解决Cypress 10集成Ethereal邮件服务的任务返回undefined问题

问题根源

你的getUserEmail任务返回undefined,核心原因是:

  1. makeEmailAccount()如果是异步创建Ethereal账号(比如依赖nodemailer.createTestAccount()这个异步方法),你在任务里同步调用它会导致emailAccount是一个未resolved的Promise对象,而非实际的账号数据,因此emailAccount.email为undefined。
  2. 任务中重复创建账号不仅没必要,还会因为异步时序问题导致数据未初始化完成。
  3. 原配置代码存在语法缺失(如未闭合大括号、未返回config),也会影响Cypress的任务处理逻辑。

修复步骤

1. 确保email-account.js返回异步创建的账号对象

修改cypress/support/email-account.js,确保它通过async/await正确初始化Ethereal账号:

const nodemailer = require('nodemailer')
const Imap = require('imap')
const { simpleParser } = require('mailparser')

module.exports = async function makeEmailAccount() {
  // 创建Ethereal测试账号
  const account = await nodemailer.createTestAccount()

  // 配置IMAP用于获取邮件
  const imapConfig = {
    user: account.user,
    password: account.pass,
    host: 'imap.ethereal.email',
    port: 993,
    tls: true,
    tlsOptions: { rejectUnauthorized: false }
  }

  // 获取最新邮件的方法
  async function getLastEmail() {
    return new Promise((resolve, reject) => {
      const imap = new Imap(imapConfig)

      imap.once('ready', () => {
        imap.openBox('INBOX', false, (err, box) => {
          if (err) reject(err)
          // 搜索最新的一封邮件
          const searchCriteria = ['ALL']
          const fetchOptions = { bodies: '', markSeen: false }
          imap.search(searchCriteria, (err, results) => {
            if (err) reject(err)
            if (!results.length) return resolve(null)
            
            const fetch = imap.fetch(results[results.length - 1], fetchOptions)
            fetch.on('message', (msg) => {
              msg.on('body', (stream) => {
                simpleParser(stream, (err, parsed) => {
                  if (err) reject(err)
                  resolve(parsed)
                  imap.end()
                })
              })
            })
          })
        })
      })

      imap.once('error', (err) => reject(err))
      imap.once('end', () => {})
      imap.connect()
    })
  }

  return {
    email: account.user,
    getLastEmail
  }
}

2. 修正cypress.config.js的任务配置

调整配置文件,在setupNodeEvents中异步初始化账号,避免重复创建,并修正语法问题:

const { defineConfig } = require('cypress')
const { isFileExist } = require('cy-verify-downloads')
const makeEmailAccount = require('./cypress/support/email-account')

module.exports = defineConfig({
  e2e: {
    async setupNodeEvents(on, config) {
      // 异步初始化Ethereal账号,确保拿到完整数据
      const emailAccount = await makeEmailAccount()

      on('task', {
        // 直接返回已初始化的账号邮箱
        getUserEmail() {
          return emailAccount.email
        },

        // 异步获取最新邮件,需加async/await
        async getLastEmail() {
          return await emailAccount.getLastEmail()
        },

        // 注册其他任务
        isFileExist
      })

      // 必须返回config,Cypress 10+要求
      return config
    }
  }
})

3. 测试用例中的调用方式

在测试用例中正常调用任务即可:

cy.task('getUserEmail').then(email => {
  // 使用邮箱进行测试,比如注册、发送验证邮件
  cy.log(`测试邮箱:${email}`)
})

// 等待邮件发送后获取最新邮件
cy.task('getLastEmail').then(email => {
  expect(email).to.not.be.null
  expect(email.subject).to.equal('你的验证邮件')
})

关键注意事项

  • 确保安装了所需依赖:npm install nodemailer imap mailparser --save-dev
  • 不要在任务中重复创建账号,避免异步时序问题和资源浪费
  • Cypress 10+的setupNodeEvents支持async函数,可直接用await处理异步初始化

内容的提问来源于stack exchange,提问作者Ashok Negi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 02:17:35