首页 > 解决方案 > Protractor Fetching Email with Mail Listener: TypeError: deferred.fulfill is not a function

问题描述

I am getting the following error when trying to fetch an email with mail-listener2 and protractor:

[17:29:50] E/launcher - TypeError: deferred.fulfill is not a function

The purpose of the step is to ensure the deferred promise is executed i.e. a mail is received.

Step:

await browser.wait(MailHelper.getLastEmail, 6000);

Mail helper:

import { protractor } from 'protractor';

export class MailHelper {
    static getLastEmail() {
        const deferred: any = protractor.promise.defer();
        console.log('Waiting for an email...');
        const globalAny: any = global;

        globalAny.mailListener.on('mail', function (mail, seqno, attributes) {
            console.log(`Received: ${mail.subject}`);
            deferred.fulfill(mail);
        });
        return deferred.promise;
    }
}

Protractor config:

// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

exports.config = {
  SELENIUM_PROMISE_MANAGER: false,
  allScriptsTimeout: 50000,
  getPageTimeout: 50000,
  // specs: [
  //   './src/**/*.e2e-spec.ts'
  // ],
  specs: ['./src/features/**/*.feature'],
  capabilities: {
    'browserName': 'chrome'
  },
  directConnect: true,
  baseUrl: 'http://localhost:4200/',
  framework: 'custom',
  frameworkPath: require.resolve('protractor-cucumber-framework'),
  cucumberOpts: {
    require: [
      './src/steps/**/*.steps.ts'
    ],
    tags: "@debug"
  },
  onPrepare() {
    require('ts-node').register({
      project: require('path').join(__dirname, './tsconfig.e2e.json')
    });

    return new Promise((resolve, reject) => {

      var MailListener = require("mail-listener2");

      var mailListener = new MailListener({
        username: "xxx@gmail.com",
        password: "test",
        host: "imap.gmail.com",
        port: 993,
        tls: true,
        tlsOptions: { rejectUnauthorized: false },
        mailbox: "INBOX"
      });

      mailListener.start();

      mailListener.on("server:connected", function () {
        console.log("Mail listener initialized");
        resolve();
      });

      mailListener.on("server:disconnected", function () {
        console.log("imapDisconnected");
      });

      mailListener.on("error", function (err) {
        console.log('MailListener error: ' + err);
        reject(err);
      });

      global.mailListener = mailListener;
    });
  },
  onCleanUp: function () {
    mailListener.stop();
  }
};

标签: javascriptangularprotractor

解决方案


问题似乎是量角器承诺 API。不确定您使用的是哪个版本的量角器。

无论如何,当您使用 async/await 时,为什么不直接使用 Promise 而不是依赖 Protractor Promise?

这是一个执行相同但使用Promise的代码片段

export class MailHelper {
  static getLastEmail() {
    const globalAny: any = global;
    return new Promise((resolve, reject) => {
      globalAny.mailListener.on('mail', function (mail, seqno, attributes) {
        resolve(mail);
      });
    });
  }
}

希望有帮助...


推荐阅读