如何使用capybara访问电子邮件中的链接

时间:2014-08-11 09:33:49

标签: ruby testing selenium cucumber capybara

我是水豚黄瓜的新手。我有一个应用程序来测试其流程是:'在提交表单后,将向用户发送一封电子邮件,其中包含指向另一个应用程序的链接。为了访问应用程序,我们必须打开邮件并单击链接,该链接将重定向到应用程序。我无权访问邮件ID。有没有办法提取该链接并继续流程? 请给出一些可行的方法。

此致 Abhisek Das

3 个答案:

答案 0 :(得分:6)

在测试中,使用您需要的任何方法来触发应用程序发送电子邮件。发送电子邮件后,使用正则表达式从电子邮件正文中的链接中查找URL(请注意,这仅适用于包含单个链接的电子邮件),然后访问Capybara中该URL的路径以继续你的考试:

path_regex = /(?:"https?\:\/\/.*?)(\/.*?)(?:")/    

email = ActionMailer::Base.deliveries.last
path = email.body.match(path_regex)[1]
visit(path)


正则表达式解释

正则表达式(正则表达式)本身由正斜杠划分,此正则表达式特别包含三个,每个由括号括起来。第一组和第三组均以?:开头,表示它们是非捕获组,而第二组是捕获组(无{{1} })。我将在下面解释这种区别的重要性。

第一组?:是:

  • 非捕获组,(?:"https?\:\/\/.*?)
  • 匹配单个双引号,?:
    • 我们匹配报价,因为我们预计该网址位于链接标记的"属性中
  • 后跟字符串href="..."
  • 可选地后跟小写的 s http
    • 问号会产生前一个匹配,在本例中为s?,可选
  • 后跟一个冒号和两个正斜杠,s
    • 注意反斜杠,用于转义字符,否则在正则表达式中具有特殊含义
  • 后跟一个通配符\:\/\/,它将匹配任何字符,直到达到正则表达式中的下一个匹配为止
    • 句点或通配符匹配任何字符
    • 星号.*?,重复上一场比赛,最多不超过次数,具体取决于后面的连续比赛。
    • 问号使这个 lazy 匹配,这意味着通配符将匹配尽可能少的字符,同时仍然允许正则表达式中的下一个匹配得到满足

第二组*是一个捕获组:

  • 匹配单个正斜杠,(\/.*?)
    • 这将匹配URL的主机部分之后的第一个正斜杠(例如\/末尾的斜杠),因为http://www.example.com/中的斜杠已经与第一组匹配
  • 后跟另一个懒惰的通配符http://

第三组.*?是:

  • 另一个非捕获组(?:")
  • 匹配单个双引号?:

因此,我们的第二组将匹配URL的部分,从主机后面的正斜杠开始,然后到达"末尾的双引号,但不包括。

当我们使用正则表达式调用href="..."方法时,它返回match的实例,其行为与数组非常相似。索引MatchData处的元素是包含整个匹配字符串的字符串(来自正则表达式中的所有组),而后续索引处的元素仅包含正则表达式捕获组匹配的字符串部分(在这种情况下,只有我们的第二组)。因此,为了获得我们第二组的相应匹配 - 这是我们想要使用Capybara访问的路径 - 我们抓住索引0处的元素。

答案 1 :(得分:0)

您可以使用Nokogiri解析电子邮件正文并找到您要点击的链接。

想象一下,您想要点击链接更改密码

email = ActionMailer::Base.deliveries.last
html = Nokogiri::HTML(email.body.to_s)
target_url = html.at("a:contains('Change my password')")['href']
visit target_url

我认为使用正则表达式更加语义和健壮。例如,如果电子邮件有许多链接,这将有效。

答案 2 :(得分:0)

如果您正在使用或愿意使用capybara-email gem,现在有一种更简单的方法。假设您已生成一封电子邮件到recipient@email.com,其中包含链接“ fancy link”。

然后,您可以在测试套件中执行此操作:

open_email('recipient@email.com') # Allows the current_email method
current_email.click_link 'fancy link'