Testing user sign-up for real! (Jest, Puppeteer, and test email accounts)
Tags: react, javascript, tutorial, testing
Published: 2020-04-28 14:33:03

![react](https://www.mailslurp.com/assets/brands/react-puppeteer.png)

Jest is a test framework popular in the React community and Puppeteer is a headless browser library. Together, using jest-puppeteer and MailSlurp (a FREE email API), we can write automated tests that sign up users using real email addresses in a browser. 

We can then use these email addresses to receive confirmation codes and email notifications. This testing software combination is excellent for testing email dependent processes like user sign-up and email verification **end-to-end**.

## Writing a test

In this article we will show you how to write automated tests that generate email addresses and sign-up for a dummy authentication application. We then extract the confirmation code from an a welcome email and confirm the users account.

### Install

First create a NodeJs project:

```bash
npm init -y
```

Then install the dependencies:

```bash
npm install --save-dev jest jest-puppeteer puppeteer mailslurp-client
```

### Configure

Next we need to setup Jest to find our tests and to use puppeteer. Edit `package.json` to include the following:

```json
{
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "preset": "jest-puppeteer",
    "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.[jt]sx?$"
  }
}
```

### Loading the playground

We will use the MailSlurp [authentication playground](https://playground.mailslurp.com) to sign-up a user. We will then receive a verification email and extract the code and verify the account. The playground website looks like this:

![[playground]](https://www.mailslurp.com/assets/screenshots/playground/login.png)

To load this site in a Jest test let's create one:

```bash
touch sign-up.test.js
```

Inside the test let's add code to load the playground in a headless browser.

```javascript
const assert = require('assert');
const MailSlurp = require('mailslurp-client').default;
const mailslurp = new MailSlurp({ apiKey: process.env.API_KEY });

describe('sign-up process', () => {

  it('can load oauth demo site', async () => {
    await page.goto('https://playground.mailslurp.com')
    await expect(page).toMatch('Sign in to your account')
  })
```

If we now run this test we will see the following result:

```bash
$ API_KEY=your-api-key npm t

PASS  ./sign-up.test.js (1.165s)
  sign-up process
  ✓ can load oauth demo site (567ms)
```

### Testing the sign-up process

Now that we know how to write tests let's use MailSlurp to sign-up with a new email address. We can generate test email accounts on demand with MailSlurp and use them to test email processes.

```javascript
it("can click sign up link", async () => {
  await expect(page).toClick('[data-test="sign-in-create-account-link"]');
  await expect(page).toMatch("Testable Sign Up Form");
});

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

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

  // fill out the new user form with generating email address
  await expect(page).toFillForm('[data-test="sign-up-body-section"]', {
    email: inbox.emailAddress,
    password: password
  });

  // submit the new user form (which will send a confirmation email)
  await expect(page).toClick('[data-test="sign-up-create-account-button"]');
});
```

### Receiving the welcome email

Once we have signed up a user we should then receive the confirmation email inside the test using MailSlurp and extract the confirmation code:

```javascript
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];
});
```

### Confirming the account

Now that we have received the email address in code we can use Jest and Puppeteer to fill out the confirmation form and submit the confirmation code.

```javascript
it("can enter confirmation code and confirm user", async () => {
  await expect(page).toFillForm('[data-test="confirm-sign-up-body-section"]', {
    code: code
  });
  await expect(page).toClick('[data-test="confirm-sign-up-confirm-button"]');
});
```

### Test user login

Now that our account is confirmed we can login with the email address we generated and the test password. The end result should show a welcome screen

```javascript
  it('can log in with confirmed account', async () => {
    await expect(page).toMatch('Sign in to your account')
    // fill out username (email) and password
    await expect(page).toFillForm('#root', {
      username: inbox.emailAddress,
      password: password
    })
    // submit
    await expect(page).toClick('[data-test="sign-in-sign-in-button"]')
  });

  it('shows the successful greeting', async () => {
    await page.waitForFunction('document.body.innerText.includes("Welcome")');
    await expect(page).toMatchElement('h1', { text: 'Welcome' })
  })
})
```

A screenshot of the welcome screen shown after successful logins:

![welcome](https://www.mailslurp.com/assets/screenshots/playground/welcome.png)

### Running the example

Now when we execute our tests we can see a full sign-up, confirmation, and login flow being tested with real email addresses.

```bash
PASS  ./sign-up.test.js (9.165s)
    sign-up process
    ✓ can load oauth demo site (567ms)
    ✓ can click sign up link (18ms)
    ✓ can sign-up with a new email address (1733ms)
    ✓ can fetch confirmation code (2868ms)
    ✓ can enter confirmation code and confirm user (104ms)
    ✓ can log in with confirmed account (690ms)
    ✓ shows the successful greeting (2948ms)
```

We hope this example helps. For more information please see:

- [MailSlurp Documentation](https://www.mailslurp.com/docs/)
- [Jest Puppeteer Documentation](https://github.com/smooth-code/jest-puppeteer)