How to Automate Email Verification in Selenium

On August 09, 2024
9min read
Aleksandr Varnin Full Stack Developer @ Railsware

Selenium is a popular open-source tool for automating software testing. With the Selenium WebDriver, you can test web applications across diverse platforms and browsers. Selenium tests can be written in various programming languages, including Java, JavaScript, PHP, Python, and Ruby. 

The Selenium WebDriver allows you to verify the performance of web applications; that is, to test if they work as expected. Instead of testing the functionalities manually, you can use the tool to enhance the efficiency of the process.

In this tutorial, we’re going to see how to automate email verification in Selenium using the Java programming language. We’ll aim to validate if an email has been received by using Selenium to extract some text from the delivered message, automatically.

We’ll also show you how to run the automation with Mailtrap API. When advanced protection is enabled for Mailtrap’s sign-in page (reCAPTCHA), we block bots, so UI testing with Selenium WebDriver won’t work. But if you set it up via API, there won’t be any problems, even with the advanced protection.  

So, let’s get going…

Prerequisites

Here are the resources we’ll need in this project:

  • Mailtrap – If you haven’t yet, you’ll need to register to access our pre-production testing environment. There, you’ll get your SMTP credentials, which you can use in your development environment to test emails.
  • Java Development Kit (JDK) – You can download and install it from here.
  • IntelliJ IDEA Community – You can download and install it from here. Remember that you can also use any other Java IDE of your choice.

Setting Up Our Project

Let’s start by opening IntelliJ IDEA and pressing ‘New Project’:

IntelliJ IDEA setup

Then:

  • Select Java
  • Name your project
  • Choose your preferred build system (I’ll use Gradle in this tutorial)
  • Select the Java version
  • Press ‘Create’
Selenium tutorial

And here’s how your project layout should look like:

Selenium Project

Next, we need to create a new Class file, which we can do by right-clicking on the java folder inside the test directory. As we’re using Selenium for testing, let’s select New > Java Class, and name it TestEmail. This class will contain the coding logic for using Selenium for email validation.

Selenium new class file

Then, let’s add the Selenium dependencies for our project by opening the build.gradle file and adding the following dependencies:

testImplementation("org.seleniumhq.selenium:selenium-java:4.22.0")
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.3")
testImplementation("org.json:json:20240303")

Once you add the dependencies, simply press ‘Load Gradle Changes’.

Selenium Load Graddle Changes

After successfully setting up our project, we can now start getting our hands dirty by writing a script that can verify email using Selenium.

Test Emails With Mailtrap and Selenium

Reminder: UI testing with Selenium WebDriver doesn’t work with advanced sign-up protection. Please use our API instead. 

On that note, we’re going to demonstrate how you can use Selenium to verify if a user has received an email message, assuming the advanced protection is off. So, we’ll use the tool to log into our Mailtrap account automatically and check if the message has been delivered.

Sounds exciting?

We’ve got sending emails in Java, also via the Mailtrap SMTP server, covered in another article.

To begin with, let’s import the following packages that we’ll need in this project:

  • org.junit.jupiter.api.Assertions – A JUnit 5 class that provides a collection of static methods to support various assertion functionalities used in unit testing.
  • org.junit.jupiter.api.Test – iA JUnit 5 annotation that denotes a method as a test method, which can be run by the test runner to execute unit tests.
  • org.openqa.selenium.* – A package that allows us to access the Selenium capabilities for automating web tests. 
  • org.openqa.selenium.chrome.ChromeDriver – This package has the ChromeDriver class required to initialize a Chrome-focused driver onto the browser that the WebDriver class has instantiated. If you’re using another web browser, which is not Chrome, you can import its driver server according to the instructions on the Selenium official website referenced previously.
  • java.util.List – Since the email messages in the Mailtrap platform are contained within an unordered list element, we’ll use this Java interface to access them.
  • java.time.Duration – A class in the Java Date and Time API that represents a time-based amount of time.

After importing the necessary packages, let’s add a new test method and create an instance of the Selenium WebDriver and set it to our desired browser. 

@Test
public void checkEmailWithUI() {
    WebDriver driver = new ChromeDriver();
}

Next, let’s launch a new browser session and provide the Mailtrap’s login URL as its parameter. This way, Chrome will navigate to the specified URL automatically.

driver.get("https://mailtrap.io/signin");

Then let’s apply an implicit wait method that enables us to delay the execution by 10 seconds before any exceptions are thrown.

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

Note that if we right-click on the Mailtrap’s login form and select the inspect option, we notice that the Email field is created using the <input id=”user_email”> element. 

Therefore, to locate this HTML element using a Selenium command, we’ll use the Selenium’s WebElement interface. Basically, the WebElement represents an HTML element; it allows us to carry out various operations associated with web page interactions.

So, to identify the HTML element, we’ll call the WebDriver’s findElement() method, which returns the element as a WebElement object. Furthermore, we’ll use an XPath expression to specify the element’s location on the web page.

Here is the code:

WebElement email = driver.findElement(By.xpath("//*[@id=\"user_email\"]"));

Then, to set the value of the email field, we’ll call the sendKeys() method and specify our email address as its parameter.

email.sendKeys("example@gmail.com");

Now we should press the Next button. To do this, we should find it by className.

driver.findElement(By.className("login_next_button")).click();

After clicking on the Next button the password field appears.

Similarly, since the password field is created using the <input id=”user_password”> element, we’ll invoke Selenium’s WebElement interface and call the sendKeys() method to set its value.

WebElement password = driver.findElement(By.xpath("//*[@id=\"user_password\"]"));
password.sendKeys("<yourPassword>");

To complete the logging in process, we’ll locate the Log in button and use the click() method to click it. 

driver.findElement(By.xpath("//input[@type=\"submit\"]")).click();

Once we’ve successfully logged into the Mailtrap platform, we’ll select Email Testing > My Inbox, and click it so that we can access the email messages in our inbox, like so:

If we inspect the element’s code, we notice that it’s encapsulated in an <a> tag with a title attribute of “My Inbox”. So, we’ll pick this value and refer to it. By href for Email Testing menu and by title for specified inbox.

Here’s the code: 

driver.findElement(By.xpath("//a[@href=\"/inboxes\"]")).click();
driver.findElement(By.xpath("//a[@title=\"My Inbox\"]")).click();

Next, if we inspect the messages in our inbox, we notice that they are contained within an <ul> list tag.

Here is a screenshot:

So, we’ll use the contains() method to look for the list of web elements that contain the text we want. In this case, we want to verify if any of our email messages contain the words “You are awesome!”. 

Furthermore, we’ll use the isEmpty() method to validate whether the text has been found or not. In other words, this method will return true if no matching text is found in the email addresses; otherwise, it returns false. 

Consequently, we’ll use JUnit Assertions to validate the results of the Selenium script for email validation. Before Assertions we’ll close the Chrome browser associated with the WebDriver.

Here is the code:

List<WebElement> allMessages = driver.findElements(By.xpath("//*[contains(text(), 'You are awesome!')]"));
driver.quit();

Assertions.assertFalse(allMessages.isEmpty(), "There is no message in inbox. Test failed");

Testing Automation with Mailtrap API

As mentioned earlier in this tutorial, using Mailtrap API for this automation is the way to go with advanced protection. Below are the references for API calls, and we’ll show you how to render a specific email in HTML. 

Sign in with Mailtrap API token

Grab the API token and use it for calls. You can find or create your token under Settings > API Tokens, as shown in the image below. You’ll also need the Account ID, located under Settings > Account Settings.  

Mailtrap API Tokens

With that, you’ll need to copy your API Token to the Selenium WebDriver to run automated testing. Keep in mind that the token needs an Inbox Viewer or higher permissions. In this example, we’re using Inbox Admin permission.  

Check all messages

The API call below allows you to get all messages for a certain inbox. 

/api/accounts/{account_id}/inboxes/{inbox_id}

Check one message

Grab the message ID and make the API call below to get information for a specific message. Aside from verifying an email, you can get other information with this call – SMTP info, for example. 

/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id}

Render the message in a browser

From the response of the API call above, there is an HTML path. Check the snippet below as an example, and here’s the link to this call:

/api/accounts/{account_id}/inboxes/{inbox_id}/messages/{message_id}/body.html

If you use the link in the response, you’ll be able to see the HTML version of the email for this instance. Aside from that, you could also inspect other email formats, e.g. HTML source, Text, and EML. 

Wrapping Up

Here is the entire code for this tutorial on how to verify email using Selenium:

UI Method

@Test
public void checkEmailWithUI() {
   //create a Selenium WebDriver instance
   WebDriver driver = new ChromeDriver();
   //launch the Chrome browser and navigate to the website
   driver.get("https://mailtrap.io/signin");
   //puts an implicit wait for 10 seconds before throwing exceptions
   driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

   //locate the email field
   WebElement email = driver.findElement(By.xpath("//*[@id=\"user_email\"]"));
   //set the field's value
   email.sendKeys("example@gmail.com");

   //locate and click the `Next` button
   driver.findElement(By.className("login_next_button")).click();

   //locate the password field
   WebElement password = driver.findElement(By.xpath("//*[@id=\"user_password\"]"));
   //set the password's value
   password.sendKeys("<password>");

   //locate and click the `Log In` button
   driver.findElement(By.xpath("//input[@type=\"submit\"]")).click();

   //locate Inboxes and click it
   driver.findElement(By.xpath("//a[@href=\"/inboxes\"]")).click();
   //locate My Inbox and click it
   driver.findElement(By.xpath("//a[@title=\"My Inbox\"]")).click();

   //look for the given text in the list of web elements
   List<WebElement> allMessages = driver.findElements(By.xpath("//*[contains(text(), 'You are awesome!')]"));
   //close the Chrome browser.
   driver.quit();
   //check if text has been found or not
   Assertions.assertFalse(allMessages.isEmpty(), "There is no message in inbox. Test failed");
}

If we run the above code, this is what we get on the console:

Tests passed!

API Method

To stress, the code above works without advanced protection. If the advanced protection is on (e.g. reCAPTCHA), please use Mailtrap API as shown above. And here’s the entire code for the API method:

@Test
public void checkEmailWithAPI() throws URISyntaxException, IOException, InterruptedException, JSONException {
    // Define the API token for authentication
    final String apiToken = "<your-api-token>";
    // Define the account ID for Mailtrap
    final String accountId = "<your-account-id>";
    // Define the base URL for Mailtrap
    final String mailtrapUrl = "https://mailtrap.io";

    // Initialize the HTTP client for making API calls
    HttpClient client = HttpClient.newHttpClient();
    // Build the request to get inboxes for the account
    HttpRequest inboxesReq = HttpRequest.newBuilder()
            .uri(new URI(mailtrapUrl + "/api/accounts/" + accountId + "/inboxes/"))
            .header("Api-Token", apiToken)
            .header("Content-Type", "application/json")
            .GET()
            .build();

    // Send the request and get the response
    HttpResponse<String> inboxesRes = client.send(inboxesReq, HttpResponse.BodyHandlers.ofString());
    // Assert that the response status code is 200 (OK)
    Assertions.assertEquals(200, inboxesRes.statusCode(), "Cannot find inboxes for the account. Test failed");

    // Get the response body as a string
    String inboxesResponseBody = inboxesRes.body();
    // Parse the response body as a JSON array
    JSONArray inboxes = new JSONArray(inboxesResponseBody);

    // Get the first inbox ID from the array
    String inboxId = inboxes.getJSONObject(0).getBigDecimal("id").toString();

    // Build the request to get messages from the first inbox
    HttpRequest inboxMessagesReq = HttpRequest.newBuilder()
            .uri(new URI(mailtrapUrl + "/api/accounts/" + accountId + "/inboxes/" + inboxId + "/messages/"))
            .header("Api-Token", apiToken)
            .header("Content-Type", "application/json")
            .GET()
            .build();

    // Send the request and get the response
    HttpResponse<String> inboxMessagesRes = client.send(inboxMessagesReq, HttpResponse.BodyHandlers.ofString());
    // Assert that the response status code is 200 (OK)
    Assertions.assertEquals(200, inboxMessagesRes.statusCode(), "Cannot find inbox " + inboxId + ". Test failed");

    // Get the response body as a string
    String inboxMessagesResponseBody = inboxMessagesRes.body();
    // Parse the response body as a JSON array
    JSONArray messages = new JSONArray(inboxMessagesResponseBody);

    // Get the first message ID and HTML path from the array
    String messageId = messages.getJSONObject(0).getBigDecimal("id").toString();
    String messageHtmlPath = messages.getJSONObject(0).getString("html_path");

    // Build the request to get the HTML content of the first message
    HttpRequest messagesReq = HttpRequest.newBuilder()
            .uri(new URI(mailtrapUrl + messageHtmlPath))
            .header("Api-Token", apiToken)
            .header("Content-Type", "application/json")
            .GET()
            .build();

    // Send the request and get the response
    HttpResponse<String> messagesRes = client.send(messagesReq, HttpResponse.BodyHandlers.ofString());
    // Assert that the response status code is 200 (OK)
    Assertions.assertEquals(200, messagesRes.statusCode(), "Cannot find message " + messageId + ". Test failed");

    // Close the HTTP client
    client.close();

    // Create a Selenium WebDriver instance for Chrome
    WebDriver driver = new ChromeDriver();
    // Launch the browser and navigate to the HTML version of the email
    driver.get(mailtrapUrl + messageHtmlPath + "?api_token=" + apiToken);
    // Implicitly wait for 10 seconds before throwing exceptions
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

    // Check if the specific text is displayed in the email HTML content
    boolean htmlDisplayed = driver.findElement(By.xpath("//*[contains(text(), 'Congrats for sending test email with Mailtrap!')]")).isDisplayed();
    // Assert that the HTML content is displayed
    Assertions.assertTrue(htmlDisplayed, "HTML of email is not displayed. Test failed");

    // Wait for 10 seconds and close the browser
    Thread.sleep(10000);
    driver.quit();
}

If you run the code above, this is the response you get. 

Again, it worked!

Conclusion

That’s how to automate email verification in Selenium. With Selenium, you can access the contents of the delivered messages and extract some texts automatically, which lets you know whether your email application is functioning as desired.

If you want to learn more about how to use Selenium to automate web tests, you can check its official documentation on its website.

Alternatively, learn how you can easily test various user scenarios with a ready to use integration of Kakunin (E2E testing framework) + Mailtrap from our case study with The Software House.

Notably, Mailtrap offers you a robust testing platform for verifying the functionalities of your emails before distributing them to real users. You should give it a try today!

All the best with your emails. 

Article by Aleksandr Varnin Full Stack Developer @ Railsware

Comments

2 replies

dipti

this blog is very helpful for beginners it is very great information thanks for sharing keep posting

s kumar

many error / not good example for VB.NET Selenium

1 : how to hide command prompt in vb.net ( VB 2019 )

2 SendKey Ctrl V not Work in OpenQA.Selenium.Chrome

3 Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5) not good work in VB.net

4 ExecuteAsyncScript not work Fast or not get any Error in

Try

Catch ex As Exception

End Try

5 Selenium.Chrome , i think this is good work in C or C or C# , VB.net code not on any web side

6 Selenium.Chrome is good tools but not usefull for VB.NET developer

share new code with me soft.developer2k[a]gmail.com

Comments are closed.