我需要测试一个量角器测试用例,其中用户注册,收到电子邮件,转到电子邮件中提供的链接,并以激活注册表格填写他/她的详细信息。
问题是如何从电子邮件中获取兑换令牌。我的电子邮件中有一个指向激活页面的链接,其中包含以下身份验证令牌:
http://127.0.0.1:3000/#/signup/redeem/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJlOTRhYzY3MC1kYTNlLTQyYTUtODVkZS02NDU4ZjVmZGMwYjAiLCJzdWIiOiJ0ZXN0QGNvZWYuY28iLCJpYXQiOjE0Mjc0OTM5MDMsImV4cCI6MTQyODA5ODcwM30.
但是如何获取该令牌以便我可以构建网址,或者如何在电子邮件中单击该按钮以便我可以完成流程?我正在使用mailcatcher来模拟电子邮件。
答案 0 :(得分:29)
这是我最近解决的问题。希望该解决方案也适用于您的用例。
先决条件:
mail-listener2
package promises
分步说明:
安装mail-listener2
:
npm install mail-listener2 --save-dev
在您的量角器配置初始化邮件侦听器并使其全局可用:
onPrepare: function () {
var MailListener = require("mail-listener2");
// here goes your email connection configuration
var mailListener = new MailListener({
username: "imap-username",
password: "imap-password",
host: "imap-host",
port: 993, // imap port
tls: true,
tlsOptions: { rejectUnauthorized: false },
mailbox: "INBOX", // mailbox to monitor
searchFilter: ["UNSEEN", "FLAGGED"], // the search filter being used after an IDLE notification has been retrieved
markSeen: true, // all fetched email willbe marked as seen and not fetched next time
fetchUnreadOnStart: true, // use it only if you want to get all unread email on lib start. Default is `false`,
mailParserOptions: {streamAttachments: true}, // options to be passed to mailParser lib.
attachments: true, // download attachments as they are encountered to the project directory
attachmentOptions: { directory: "attachments/" } // specify a download directory for attachments
});
mailListener.start();
mailListener.on("server:connected", function(){
console.log("Mail listener initialized");
});
global.mailListener = mailListener;
}),
onCleanUp: function () {
mailListener.stop();
},
创建一个帮助getLastEmail()
函数,等待email
被检索:
function getLastEmail() {
var deferred = protractor.promise.defer();
console.log("Waiting for an email...");
mailListener.on("mail", function(mail){
deferred.fulfill(mail);
});
return deferred.promise;
};
示例测试用例:
describe("Sample test case", function () {
beforeEach(function () {
browser.get("/#login");
browser.waitForAngular();
});
it("should login with a registration code sent to an email", function () {
element(by.id("username")).sendKeys("MyUserName");
element(by.id("password")).sendKeys("MyPassword");
element(by.id("loginButton")).click();
browser.controlFlow().await(getLastEmail()).then(function (email) {
expect(email.subject).toEqual("New Registration Code");
expect(email.headers.to).toEqual("myemail@email.com");
// extract registration code from the email message
var pattern = /Registration code is: (\w+)/g;
var regCode = pattern.exec(email.text)[1];
console.log(regCode);
});
});
});
答案 1 :(得分:7)
我实施的解决方案是使用mailcatcher API,如果向下滚动一下,您会发现以下有关API的信息:
相当RESTful的URL架构意味着您可以下载消息列表 在/ messages中的JSON,每个消息的元数据 /messages/:id.json,然后是相关部分 /messages/:id.html和/messages/:id.plain用于默认HTML和 纯文本版本,/ messages /:id /:用于个别附件的cid CID,或/messages/:id.source的整个消息。
所以我们首先获取整个json响应,解析它并获取最新的电子邮件ID:
// Returns the last email id
function(emails, user) {
var email, recipient;
for(var i = emails.length - 1; i >= 0; i--) {
email = emails[i];
for(var j = 0; j < email.recipients.length ; j++) {
recipient = email.recipients[j];
if(recipient == "<"+user+">") {
return email.id;
}
}
}
};
使用该电子邮件ID我们可以通过点击/messages/:id.plain
来获取电子邮件的正文(当然还有更多变体,例如获取电子邮件源代码或电子邮件呈现的html,我们只需要消息)然后我们可以解析正文以获取我们想要的内容,以下是代码:
browser.driver.get(mailcatcherUrl+"/messages");
browser.driver.findElement(by.tagName('body')).getText().then(function(response) {
var emails, lastEmailId, partialTokens ;
emails = JSON.parse(response);
lastEmailId = getLastEmailId(emails, user);
browser.driver.get(mailcatcherUrl+"/messages/"+lastEmailId+".plain");
browser.driver.findElement(by.tagName('body')).getText().then(function(lastEmail) {
// use latestEmail to get what you want.
});
});
和干杯!
答案 2 :(得分:0)
我不得不做同样的事情,但我们使用的邮件测试服务器没有 imap 支持。 因此,如果有人遇到同样的问题,我使用 mailpop3 npm 库实现了与 alecxe 类似的解决方案。
然而,pop3 客户端的问题在于它不充当侦听器,因此我们必须定义一个辅助函数,以便在我们需要测试最新电子邮件时连接、登录并获取最新电子邮件。< /p>
像这样:
function getLastEmail() {
var deferred = protractor.promise.defer();
var POP3Client = require("mailpop3");
var client = new POP3Client(port, host, {
tlserrs: false,
enabletls: true,
debug: false
});
client.on("connect", function() {
console.log("CONNECT success");
client.login(username, password);
});
client.on("login", function(status, rawdata) {
if (status) {
console.log("LOGIN/PASS success");
client.retr(1);
} else {
console.log("LOGIN/PASS failed");
client.quit();
}
});
client.on("retr", function(status, msgnumber, data, rawdata) {
if (status === true) {
console.log("RETR success for msgnumber " + msgnumber);
deferred.fulfill(data);
} else {
console.log("RETR failed for msgnumber " + msgnumber);
}
client.quit();
});
return deferred.promise;
}