Depending on the test, it may be necessary to check the content of the email address sent or click on a link in the email. The best way to automate this process is to combine an external Email Server and a MagicPod Web API command to acquire the content of the sent email.
Here, we will show you how to use MailSlurp and the Gmail Web API that is part of the Google Workspace (previously G Suite (there is also a service called Mailtrap, but as an email address is not available with the free version, we shall not introduce that here.) Although it is simple to configure MailSlurp for use, there is a limit to the number of emails that can be sent in the free version. Setting up Gmail is more complex, and requires a Google Workspace contract; however, if your company is already using Google Workspace, you can use it without any restrictions on the number of messages that can be sent. From the perspective of ease of use and functionality, it is probably easier to implement MailSlurp.
Table of Contents
1. Method of using MailSlurp
What is MailSlurp?
This is a Web service that provides dummy email addresses and an API to send and receive them. This is mainly used for testing and development purposes. This is only available in English.
There are free and charged versions, with the free version having the following limitations.
- Only 50 email addresses can be generated per month
- Only 100 emails can be sent and received, respectively, each month
- It cannot be used for commercial use
For details, please check the Price chart. If you use the $21/month Starter plan, you will likely face few issues in terms of practical application.
Setup Method
Create an account using the “Sign up” button on the top-right of the homepage, and after logging in, copy the API Key on the Dashboard.
Generate the email address to be used in the test.
As a random value will be generated, copy "Inbox ID" of an inbox that does not contain a domain.
Define the "MAIL_API_KEY" in the Magic Pod Secret shared variable, and set the copied value.
Then, using the command to store a fixed value in a variable, define "Inbox_ID," and set it to a value copied from the inbox ID.
Next, call the Web API call command as shown in the figure below, and perform processing of user registration, etc., using the ${Inbox_ID}, and send an email to this address (this process is performed on the tested application, rather than the Web API call command).
At this time, an email will be added to your inbox for every test that you run, so we recommend that you empty the mailbox before running each test. (to specify that the email call is to be made for the –th case)
Empty the mailbox using the following Web API call.
The value to specify is as follows.
- Set method to “DELETE”
- Set the URL to “https://api.mailslurp.com/emails”. minCount=1 means to wait until the total number of emails in the inbox is greater than or equal to one. This value can be modified.
- Set the header to “x-api-key” “${MAIL_API_KEY}”
Let us try actually calling the email title and content.
The value to specify is as follows.
- Set method to “GET”
- Set the URL to “https://api.mailslurp.com/inboxes/${Inbox_ID}/emails?minCount=1”. minCount=1 means to wait until the total number of emails in the inbox is greater than or equal to one. This value can be modified.
- Set the header to “x-api-key” “${MAIL_API_KEY}”
- Set the result to “Subject”, “jsonResponse[0]["subject"]” and “MailID”, “jsonResponse[0]["id"]”. 0 refers to the first email. 1 refers to the second email, 2 refers to the third...and so on. ((There is also an option to put the latest one at the front, but this did not work very well. ))
Now the "Subject" of the first email can be referenced by ${Subject} and the "MailID" by ${MailID}.
* "MailID" is the ID for each email received by MailSlurp.
Next, we can obtain the main text of the email using the following Web API call.
The value to specify is as follows.
- Set method to “GET”
- Set the URL to “https://api.mailslurp.com/emails/${MailID}/textLines”
- Set the header to “x-api-key” “${MAIL_API_KEY}”
- Set the results to “MainText”, “jsonResponse["lines"]”
With this, the “MainText” of the first email can be acquired using ${MainText} (if the main text covers multiple lines, this will be consolidated into one line).
If you wish to extract the main text as html, specify the URL as “https://api.mailslurp.com/emails/${MailID}/html”.
Following that, you can confirm whether the content of the main body of the email is correct with the “Assertion” command, and extract only a specific part of the main text with the “Store regular expression matched part” command.
If you want to carry out processing, such as clicking the URL in the main text of the email to complete user authentication, after using the “Store regular expression matched part” command to extract the URL part,
- for a browser test, move to this URL using the “Navigate to URL”.
- for a mobile test, you can open the mobile browser with “Launch other app” (if you want to open a mobile browser from a mobile app testing script) and enter the URL into the browser
Others
- The content of the sent email can be confirmed on the MailSlurp Dashboard.
- MailSlurp includes various other API, such as those shown below. For details, check the MailSlurp documentation. (The official documentation page is currently under renovation)
- Acquire the part matching the CSS selector from the main text of an HTML email (/emails/${MailID}/htmlQuery)
- Acquire the part matching a regular expression from the main text of an HTML email (/emails/${MailID}/contentMatch)
- Wait until an email matching specified criteria is found in the inbox, and retrieve its contents when found (/waitForMatchingEmails)
- Delete mail address (DELETE method/inboxes/${Inbox_ID})
- Send email (POST method /inboxes/${Inbox_ID})
- Acquire email header information (acquire data with jsonResponse["headers"]["HeaderName"] based on results of /emails/${Mail ID})
2. Method of using the Google Workspace Gmail Web API
Acquiring the “Client ID” and “Client secret”
First, acquire the “Client ID” and “Client secret” required for authenticating the Web API.
First, prepare one test Google account (= Gmail account) belonging to G Suite (this should be a different account than the one you normally use, as the Web API will allow you to retrieve email content). ((Although it is technically possible to use a Web API with an e-mail address that does not belong to G Suite, it is very difficult to obtain a token that does not expire. ))
Next, sign into the Google Developer Console with the Google account you created and create a “project” with your favorite project name.
Next, select “ENABLE APIS AND SERVICES” from “APIs & Services”>”Enabled APIs & services” in the menu at the top left of the screen.
And select the Gmail API to enable it.
It is necessary to enable OAuth first in order to authenticate the API. First, select the “API and service” > “OAuth consent screen” from the menu on the top left of the screen. For a G Suite email address, select “Internal” for the “User Type”. It is possible to send a test as “External” as well, but the token will expire in a few days. ((If it is not a G Suite email address, “Internal” will not be able to be selected. If you select “External” and receive confirmation via Google, it will likely be possible to get non-G Suite email addresses with tokens that do not expire, but it is very difficult to get these approved. )).
On the next screen, specify the appropriate "App name", and select "User support email."
And further click "ADD OR REMOVE SCOPES."
Select "View your email messages and settings" in "Scope" and click "UPDATE". OAuth will now be enabled.
And click "SAVE AND CONTINUE."
Proceed "Summary", click "BACK TO DASHBOARD."
Next, create the “Authentication information”. From the menu at the top left of the screen, select "APIs & Services" > "Credentials" > "CREATE CREDENTIALS" > "OAuth client ID."
Then select "Application type" as "Desktop app" and click "CREATE".
If you do this, the "Client ID," "Client Secret," and a button to download the JSON file will appear on the screen.
And it will save the JSON file with the name "credentials.json" in an appropriate directory.
Acquiring “Refresh Tokens”
Next, acquire a "refresh token." This is also required for Web API authentication.
Here, we shall explain the procedure using Python. (For other APIs, see https://developers.google.com/gmail/api/guides/quickstarts-overview)
First, if Python is not installed on your machine, follow the instructions here to install it.
Next, open the command prompt for Windows or the terminal of Mac and run the following command.
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
You have now downloaded the Google client library.
Next, create an empty file after starting an editor in an appropriate directory on your machine. Next, click the “Copy code sample” button from this page, and copy and paste the contents.
Save the file you created as “quickstart.py”.
Next, move “credentials.json,” which was just saved, to the same directory as “quickstart.py.”
And run them from the command line.
cd <directory in quickstart.py>
python quickstart.py
If you do this, a page like the one shown in the figure below shall be displayed, so click “Allow” to close the window.
A file named "token.json" will be created in the same directory, and the "client ID," "client secret," and "refresh token" can be checked from here.
Test script to acquire the main text of the email
Now that we have the "Client ID," "Client Secret," and "Refresh Token," we can call the Gmail API from our Magic Pod test script.
First, define the three elements of CLIENT_ID, CLIENT_SECRET, and REFRESH_TOKEN in Secret shared variables, and set the values just acquired for each, respectively.
Next, call the Web API call command shown in the figure below, and acquire the latest “access token” based on the refresh token.
The specified value is as follows.
- Set method to “POST”
- Set the URL to “https://accounts.google.com/o/oauth2/token”
- Set the header to “Content-Type” “application/x-www-form-urlencoded”
- Set body “raw data” to ”client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&refresh_token=${REFRESH_TOKEN}&grant_type=refresh_token”
- Set the results to “ACCESS_TOKEN” “jsonResponse["access_token"]”
If you run this, the value of the access token will be set in the ACCESS_TOKEN variable ((the acquired access token can be used multiple times within a 30-minute period. )) .
Next, we can use this access token to retrieve a list of emails that match the specified criteria. On this occasion, we shall call the Web API call as follows:
The specified value is as follows.
- Set method to “GET”
- Set URL to “https://www.googleapis.com/gmail/v1/users/me/messages/?q=<search conditions>”. The <Search conditions> part can use the Gmail search condition notation as is. For example, this can be written as shown below (see here for the detailed notation).
- q=new_user12345678 (acquire an email including “new_user12345678” in the main text)
- q="from:no-reply@magic-pod.com" (acquire email sent from “no-reply@magic-pod.com”)
- q="subject:New user registration" (acquire email that includes “New user registration” in the title)
- Set the header to “Authorization” “Bearer ${ACCESS_TOKEN}”
- Set the results to “MAIL_ID” “jsonResponse["messages"][0]["id"]”
If you run this, the variable “MAIL_ID” will contain the ID of the latest e-mail that matches the <search criteria>.
Next, we shall acquire the main text of the email that matches this MAIL_ID. Call the Web API call as shown below.
The specified value is as follows.
- Set method to “GET”
- Set URL to “https://www.googleapis.com/gmail/v1/users/me/messages/${MAIL_ID}”
- Set the header to “Authorization” “Bearer ${ACCESS_TOKEN}”
- Enter "MAIL_CONTENTS" for the results variable, and copy and paste the following into the resulting Javascript ((line feed characters will be lost, but this will not affect the operation))
const inlineMessagePart = function(messagePart) {
let messagePartBodies = [{"mimeType": messagePart.mimeType, "body": messagePart.body}];
if ("parts" in messagePart) {
for (const subMsgPart of messagePart["parts"]) {
messagePartBodies = messagePartBodies.concat(inlineMessagePart(subMsgPart));
}
}
return messagePartBodies;
};
atob([jsonResponse['payload']].map(inlineMessagePart).flat().filter(function(item) { return item.mimeType === "text/plain"; })[0]['body']['data']);
In this way, the main text of the email shall be saved in the MAIL_CONTENTS variable.
Supplementary information: Regarding Javascript that can be used to assign the variable MAIL_CONTENTS
When handling email as a program, you need to be aware of its data structure. In the case of HTML email, this data may have a hierarchical structure (in the case of a simple text email, this will not have a hierarchical structure). Therefore, the Javascript used to assign the "MAIL_CONTENTS" variable is processed as follows.
- Flatten the data structure of the email
- Search for a message part for which the MIME type is text/plain. This is used to retrieve the body of an email from a simple text email, or to retrieve alternate text from an HTML email for environments where the HTML email cannot be viewed.
- Acquire data from two message parts (replacement text for main text of email or HTML email). This data is a Base64 character string, so convert it to UTF8.
In the following two cases, the Javascript may fail to retrieve the main text of the email.
1. If the email in the test is an HTML email and there is no alternative text
If there is no message part where the MIME type is text/plain. In this case, if the Javascript ‘item.mimeType === "text/plain"’ described above is replaced by ‘item.mimeType === "text/html"’, it should be possible to obtain the main text of the email.
2. In case there are multiple places where the message parts are MIME type text/plain
If this is the case, it is possible that unintended email text may be obtained. In this case, we apologize for the inconvenience and request that you contact MagicPod support. They will provide a different workaround.
Reference
Refer here for a rough understanding of the email data structure. Refer here for more information on the Gmail Web API data structure.