Overview:
Some of our automated tests might require email validation. Your application might send a Welcome email / User registration confirmation with a link to activate the profile / a token to login as part of Multi-factor Authentication…etc. Your aim could be to check if the email has received or extract some information like auth token from the email message.
Sometimes, applications might expect unique email addresses. In that case, we end up using some random email addresses like random-string@gmail.com. Of-course this is not a valid email address. Your application does not care as long as it is in the expected format & not used already. However, if your application tries to send any email as part of your tests for that random email, How will you verify?
Would it not be legendaryyyyyyyyyyyyyyyy as Barney would say if we could have an API which generates a Valid & Random email address every time through which you could receive emails?
Lets see how we could achieve that!
Sample Application:
As usual, to explain things better, I consider this site to send an email. When you enter an email id and click on check, a test email is sent to the given email id immediately. Lets consider this as our application and we need to verify if it sends an email correctly to the given email address!
We create a Page Object for the above page as shown here.
public class IsMyEmailWorkingPage {
private final WebDriver driver;
@FindBy(id="verify_email")
private WebElement email;
@FindBy(id="content_cob_check")
private WebElement checkBtn;
public IsMyEmailWorkingPage(final WebDriver driver){
this.driver = driver;
PageFactory.initElements(driver, this);
}
public void goTo(){
this.driver.get("http://ismyemailworking.com");
}
public void checkEmail(final String emailAddress){
this.email.sendKeys(emailAddress);
this.checkBtn.click();
}
}
Nada – EMail API:
To test our sample website, we want a random working email. So, I am considering this site which uses some API internally. Nada website creates random working email addresses. No worries. We will not be using the web interface. We would use its API which the web interface uses.
Inbox API:
Nada has few email domains (ex: nada.ltd). Using that you could request for any email address!Making a GET request with an email address creates an instant Inbox for the email address.
https://getnada.com/api/v1/inboxes/{email-id}
here {email-id} could be anything. ex:
- helloworld@nada.ltd
- thisisjunk1234@nada.ltd
It does not require any password. So, If i am using helloworld@nada.ltd and you are also using it at the same time, you could see my emails. So, do not use for any sensitive information. This is just for testing purposes. msgs field in the below json is the email inbox which indicates inbox is empty.
When I enter this email address in the ‘IsMyEmailWorking’ site, I get an email as shown here.
Message API:
Inbox API gives all the list of email messages we have received for the email. If we need to get the email content, we need to get the ‘uid’ of the specific email message, then call this API.
https://getnada.com/api/v1/messages/{message-id}
Here {message-id} is the uid you had extracted from the inbox API.
EMail Service:
We have seen the APIs. So, Lets create few classes to make the HTTP calls & process the response JSON etc.
My pom file has below dependencies.
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.3</version>
</dependency>
<dependency>
<groupId>apache-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.1</version>
</dependency>
Inbox EMail:
We need to convert Nada’s inbox API response JSON to an object. So, I create this class.
@JsonIgnoreProperties(ignoreUnknown=true)
public class InboxEmail {
@JsonProperty("uid")
private String messageId;
@JsonProperty("f")
private String from;
@JsonProperty("s")
private String subject;
public String getMessageId() {
return messageId;
}
public String getFrom() {
return from;
}
public String getSubject() {
return subject;
}
}
Message Class:
To Process message API response,
@JsonIgnoreProperties(ignoreUnknown=true)
public class EmailMessage {
@JsonProperty("html")
private String html;
@JsonProperty("text")
private String text;
public String getHtml() {
return html;
}
public String getText() {
return text;
}
}
NadaEMailService:
public class NadaEMailService {
private static final String NADA_EMAIL_DOMAIN = "@nada.ltd";
private static final String INBOX_MESSAGE_KEY_NAME = "msgs";
private static final String EMAIL_ID_ROUTE_PARAM = "email-id";
private static final String MESSAGE_ID_ROUTE_PARAM = "message-id";
private static final String NADA_EMAIL_INBOX_API = "https://getnada.com/api/v1/inboxes/{email-id}";
private static final String NADA_EMAIL_MESSAGE_API = "https://getnada.com/api/v1/messages/{message-id}";
private static final ObjectMapper MAPPER = new ObjectMapper();
private static final int EMAIL_CHARS_LENGTH = 10;
private String emailId;
private void generateEmailId(){
this.emailId = RandomStringUtils.randomAlphanumeric(EMAIL_CHARS_LENGTH).toLowerCase().concat(NADA_EMAIL_DOMAIN);
}
//generates a random email for the first time.
//call reset for a new random email
public String getEmailId(){
if(Objects.isNull(this.emailId)){
this.generateEmailId();
}
return this.emailId;
}
//to re-generate a new random email id
public void reset(){
this.emailId = null;
}
public List<InboxEmail> getInbox() {
String msgs = Unirest.get(NADA_EMAIL_INBOX_API)
.routeParam(EMAIL_ID_ROUTE_PARAM, this.getEmailId())
.asJson()
.getBody()
.getObject()
.getJSONArray(INBOX_MESSAGE_KEY_NAME)
.toString();
return MAPPER.readValue(msgs, new TypeReference<List<InboxEmail>>() {});
}
public EmailMessage getMessageById(final String messageId) {
String msgs = Unirest.get(NADA_EMAIL_MESSAGE_API)
.routeParam(MESSAGE_ID_ROUTE_PARAM, messageId)
.asJson()
.getBody()
.getObject()
.toString();
return MAPPER.readValue(msgs, EmailMessage.class);
}
public EmailMessage getMessageWithSubjectStartsWith(final String emailSubject) {
return this.getInbox()
.stream()
.filter(ie -> ie.getSubject().startsWith(emailSubject))
.findFirst()
.map(InboxEmail::getMessageId)
.map(this::getMessageById)
.orElseThrow(IllegalArgumentException::new);
}
}
Our API exposes 5 methods.
- getEmailId – generates a random email. Once generated for an instance, it is always reusing the same email. If you want a new one, call reset method
- reset – nullifies the email id. so that we could re-generate new random email id
- getInbox – list of inbox messages
- getMessageById – pass the id of the message to get the content
- getMessageWithSubjectStartsWith – pass the email subject to get the latest message
Sample Test:
public class EmailTest {
private NadaEMailService nada;
private WebDriver driver;
private IsMyEmailWorkingPage page;
@BeforeTest
public void setup() {
nada = new NadaEMailService();
driver = DriverManager.getDriver();
page = new IsMyEmailWorkingPage(driver);
}
@Test
public void emailTest() throws IOException, UnirestException {
page.goTo();
page.checkEmail(nada.getEmailId());
String emailContent = nada.getMessageWithSubjectStartsWith("IsMyEmailWorking").getText();
System.out.println(emailContent);
}
}
Summary:
Nada API is a great utility for email validation. By using Nada API, you could create N number of random email id as and when it is required & dispose. It would be extremely useful for for your tests which require unique email addresses every run!
Nada is FREE. You could help Nada’s maker by buying him a coffee here.
Happy Testing & Subscribe 🙂