TestCafe end-to-end MFA testing for user sign-up and email verification
End-to-end testing with MailSlurp, NodeJS, and TestCafe.
TestCafe is a great NodeJS framework for end-to-end testing with built in browser support. You can use MailSlurp with TestCafe to test user sign-up multi-factor authentication with real email accounts. In this post we will show you how with examples. For full code see GitHub.
MFA user sign up flow
MFA is multifactor authentication. This is a common security layer to many web applications. Commonly this involves sending a verification code to a user's email address when they sign up in order to verify their account. For this example we can use a simple React App hosted at playground.mailslurp.com. This app has a common user sign up flow that allows a user to sign up with their email address and password. Upon sign up a user is sent a confirmation code by email that they must enter into the app to confirm their account.
This is what the email looks like:
It contains a numeric code that we will use MailSlurp and a regex pattern to extract.
Automated testing
TestCafe allows you to easily write end-to-end browser tests to test an application functionality. Using MailSlurp we can test application functionality using real email accounts. TestCafe will run a browser an click elements and inputs like a normal user.
Setting up a project
Let's get started and set up a new project. Create an empty directory and add a package json.
mkdir testproject && cd $_ && echo "{}" > package.json
Next we should install MailSlurp and TestCafe:
npm install --save testcafe mailslurp
The package.json
file should look like this:
{
"name": "javascript-testcafe",
"description": "Email test MFA user sign up using TestCafe and MailSlurp",
"scripts": {
"test": "testcafe firefox mfa-test.js"
},
"dependencies": {
"mailslurp-client": "^11.3.1",
"testcafe": "^1.13.0"
}
}
Now we are ready to write some tests.
Writing tests for TestCafe
Create a test file of any name - we will call ours test mfa-test.js
.
Setup MailSlurp and fixture
TestCafe expects us to define a fixture using tagged template strings. Let's do that and add a before method to instantiate MailSlurp.
import { Selector } from "testcafe";
import { MailSlurp } from "mailslurp-client";
let mailslurp;
const password = "test-password";
// define our test that will load the playground demo app
fixture`mfa sign-up test`.page`https://playground.mailslurp.com`.before(
async (_) => {
// assert that we have set an api key environment variable
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw "No MailSlurp API KEY defined";
}
mailslurp = new MailSlurp({ apiKey });
}
);
MailSlurp lets you create real test email accounts on demand and send and receive emails in tests and code. MailSlurp is free for personal use but you need an API Key. Create a free account to get your API Key. When running the tests set API_KEY=your-api-key
as an environment variable to pass the API KEY to our test instance.
Testing user sign up
Now we can test the user sign up flow. To recap we need to perform the following steps:
- Load the playground application
- Create a test email address
- Sign up using the email address and a test password
- Receive a confirmation code to the email address
- Extract the code and submit it to the app
- Login with our verified account
The code for this is quite simple with TestCafe:
test("Can sign-up and verify account", async (t) => {
// create email address for a test user
const inbox = await mailslurp.inboxController.createInbox();
// load the page and click sign up
await t
.expect(Selector("title").innerText)
.eql("React App")
.click(Selector("[data-test=sign-in-create-account-link]"));
// wait for sign up form then fill with email address and sign up
const emailInput = await Selector('[name="email"]')();
await t
.typeText(emailInput, inbox.emailAddress)
.typeText(Selector('[name="password"]'), password)
.click(Selector("[data-test=sign-up-create-account-button]"));
// wait for verification code to arrive to email then extract code
const email = await mailslurp.waitController.waitForLatestEmail(
undefined,
undefined,
inbox.id,
undefined,
undefined,
30000,
true
);
// use regex to extract the confirmation code which is 6 digits
const code = /([0-9]{6})$/.exec(email.body)[1];
// now enter code to confirm
await t
.typeText(Selector('[name="code"]'), code)
.click(Selector('[data-test="confirm-sign-up-confirm-button"]'));
// now sign up
const username = await Selector('[name="username"]')();
await t
.typeText(username, inbox.emailAddress)
.typeText(Selector('[name="password"]'), password);
const signIn = await Selector("[data-test=sign-in-sign-in-button]")();
await t.click(signIn);
// wait for sign up
const h1 = await Selector("h1")();
await t.expect(h1.innerText).eql("Welcome");
});
That's a bit of code so let's break it down:
Creating test email accounts
We can create a test email address using MailSlurp like so:
const inbox = await mailslurp.inboxController.createInbox();
Inboxes have an id
and an emailAddress
. We can use the emailAddress
to sign up for the test app:
const emailInput = await Selector('[name="email"]')();
await t
.typeText(emailInput, inbox.emailAddress)
.typeText(Selector('[name="password"]'), password)
.click(Selector("[data-test=sign-up-create-account-button]"));
Receiving emails in tests
Once signed up we need to receive the confirmation code to proceed. We can use the MailSlurp WaitForController to do so:
const email = await mailslurp.waitController.waitForLatestEmail(
undefined,
undefined,
inbox.id,
undefined,
undefined,
30000,
true
);
// use regex to extract the confirmation code which is 6 digits
const code = /([0-9]{6})$/.exec(email.body)[1];
Then we can enter the code to confirm a user account. This is a common need for many user sign up flows:
Conclusion
Signing up with a confirmed user in our test app will show a happy dog:
TestCafe is an excellent choice for end-to-end testing. Use MailSlurp to add real email accounts to your end-to-end test suites. Create a free account today or see the developer page for more examples.