Testing User Sign-Up and Email Confirmation — how to extract MFA tokens during automated testing.

Image for post
Image for post

Background

Image for post
Image for post
How can we test applications that rely on email confirmation? MailSlurp is a free API that makes that possible.

Email testing APIs

Image for post
Image for post

An example project

Testing user sign-up

What does our app look like?

Image for post
Image for post
A demo application for testing

Testing with MailSlurp

Project setup

mkdir signup && cd $_
echo '{}' > package.json
npm install --save mailslurp-client

Add a test framework

npm install --save @wdio/cli @wdio/local-runner @wdio/mocha-framework @wdio/selenium-standalone-service
npm install --save chromedriver wdio-chromedriver-service

Configure Webdriver

const config = {
runner: "local",
path: "/",
specs: ["test/*.test.js"],
exclude: [],
maxInstances: 10,
capabilities: [
{
maxInstances: 5,
browserName: "chrome",
},
],
logLevel: "info",
bail: 0,
baseUrl: "https://playground.mailslurp.com",
waitforTimeout: 30000,
connectionRetryTimeout: 90000,
connectionRetryCount: 3,
framework: "mocha",
services: ["chromedriver"],
reporters: ["spec"],
mochaOpts: {
ui: "bdd",
timeout: 60000,
},
};

exports.config = config;

Add a test command

{
"scripts": {
"test": "wdio wdio.conf.js"
},
"dependencies": {
"@wdio/cli": "^5.13.2",
"@wdio/local-runner": "^5.13.2",
"@wdio/mocha-framework": "^5.13.2",
"@wdio/selenium-standalone-service": "^5.13.2",
"@wdio/spec-reporter": "^5.13.2",
"chromedriver": "^78.0.1",
"mailslurp-client": "^6.5.0",
"wdio-chromedriver-service": "^5.0.2"
}
}

Writing a test

mkdir test
touch test/sign-up.test.js

Defining test requirements

Special needs (why we use a email testing API)

Generating test email accounts

const MailSlurp = require("mailslurp-client").default;
const apiKey = process.env.API_KEY;
const mailslurp = new MailSlurp({ apiKey });
const { emailAddress, id } = await mailslurp.createInbox();

Testing user sign-up with disposable email addresses

const assert = require("assert");

describe("sign up page", () => {
it("can load playground app", async () => {
await browser.url("/");
await browser.setWindowSize(1200, 1200);
});
});
it("can load the sign-up section", async () => {
await $('[data-test="sign-in-create-account-link"]').then((e) => e.click());
await $(".sign-up-header-section")
.then((e) => e.getText())
.then((text) => assert.strictEqual(text, "Testable Sign Up Form"));
});
API_KEY=your-mailslurp-api-key npm run test
[chrome  linux #0-0] Running: chrome on linux
[chrome linux #0-0]
[chrome linux #0-0] sign up page
[chrome linux #0-0] ✓ can load playground app
[chrome linux #0-0] ✓ can load the sign-up section
[chrome linux #0-0]
[chrome linux #0-0] 2 passing (607ms)


Spec Files: 1 passed, 1 total (100% completed) in 00:00:01

Signing up

let inbox;
let password = "test-password";

it("can sign-up with test email account", async () => {
// create a new email address for the test run
inbox = await mailslurp.createInbox();

// fill out and submit the new user form
await $('[name="email"]').then((e) => e.setValue(inbox.emailAddress));
await $('[name="password"]').then((e) => e.setValue(password));
await $('[data-test="sign-up-create-account-button"]').then((e) => e.click());
});
Image for post
Image for post

Capturing email confirmation code in tests

it("can fetch confirmation code", async () => {
// fetch the email from mailslurp
const email = await mailslurp.waitForLatestEmail(inbox.id);

// verify that it contains the code
assert.strictEqual(/verification code is/.test(email.body), true);

// extract the confirmation code
code = /([0-9]{6})$/.exec(email.body)[1];
});

it("can enter confirmation code and confirm user", async () => {
await $('[name="code"]').then((e) => e.setValue(code));
await $('[data-test="confirm-sign-up-confirm-button"]').then((e) =>
e.click()
);
});
Image for post
Image for post
\code = /([0-9]{6})$/.exec(email.body)[1];

Logging in with confirmed account

Image for post
Image for post
it("can log in with confirmed account", async () => {
// assert we see the sign in form
await $('[data-test="sign-in-header-section"]')
.then((e) => e.getText())
.then((text) => assert.strictEqual(text, "Sign in to your account"));

// fill out username (email) and password
await $('[name="username"]').then((e) => e.setValue(inbox.emailAddress));
await $('[name="password"]').then((e) => e.setValue(password));

// submit
await $('[data-test="sign-in-sign-in-button"]').then((e) => e.click());
});

it("shows the successful greeting", async () => {
await $('[data-test="greetings-nav-bar"]')
.then((e) => e.getText())
.then((text) => assert.strictEqual(/Hello/.test(text), true));
});

In summary

Code samples

Test Email API for end-to-end with real email addresses. Support for NodeJS, PHP, Python, Ruby, Java, C# and more. See https://www.mailslurp.com for details.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store