TestCafe end-to-end MFA testing for user sign-up and email verification

test cafe

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:

confirm

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.

sign-up

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 let’s 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(
    inbox.id,
    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:

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]"));

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(
  inbox.id,
  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:

sign up

Conclusion

Signing up with a confirmed user in our test app will show a happy dog:

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.