Testing SMS OTP text messages using Cypress JS.

One time password SMS code integration testing using real phone numbers and browsers.

cypress testing sms

Cypress is a browser automation tool that can be used with MailSlurp to test SMS automation such as login and sign-up app flows. In this post we will demonstrate how to setup Cypress to fetch and read real text messages from phone numbers we create in MailSlurp. We will use the Cypress SMS plugin to achieve this (or we could use the MailSlurp client directly).

The code for this examples can be found on Github.

Setup and install

First install Cypress JS and configure the config file:

import { defineConfig } from 'cypress'

export default defineConfig({
  requestTimeout: 30000,
  responseTimeout: 30000,
  defaultCommandTimeout: 30000,
  e2e: {
    testIsolation: false,
    // We've imported your old cypress plugins here.
    // You may want to clean this up later by importing these.
    setupNodeEvents(on, config) {
      return require('./cypress/plugins/index.js')(on, config)

Write a test

We will test the sign-up process for a demonstration app. The app allows sign-up with a phone number and sends a verification code to the users via SMS. The code must then be extracted and entered into the app to complete sign-up.

/// <reference types="cypress-mailslurp" />

describe("user sign up test with mailslurp plugin", function () {
    // use cypress-mailslurp plugin to fetch a phone number we created
    before(function () {
        cy.log("Wrap phone before test")
        return cy.mailslurp()
            // fetch a phone number using the phone controller on the mailslurp instance
            .then(mailslurp => mailslurp.phoneController.getPhoneNumbers({
                phoneCountry: 'US' as any,
            .then(phones => {
                // insure you have phone number created in dashboard
                // IMPORTANT STEP, add the phone number details to the test context using `cy.wrap`
                const phoneNumber = phones.content![0];
                cy.log(`Phone id ${phoneNumber.id}`)
    it("01 - can load the demo sms application", function () {
        // get wrapped phone number and assert is a US number
        // visit the demo application
        cy.title().should('contain', 'React App');
    // use function instead of arrow syntax to access aliased values on this
    it("02 - can sign up using phone number", function () {
        // click sign up and fill out the form
        // use the phone number and a test password
        cy.get("[name=phone_line_number]").type(this.phoneNumber.replace('+1', '')).trigger('change');
        // click the submit button
    it("03 - can receive confirmation code by SMS", function () {
        // app will send user an SMS containing a code, use mailslurp to wait for method to wait for the latest SMS to arrive then read the code
            // use inbox id and a timeout of 30 seconds
            .then(mailslurp => mailslurp.waitController.waitForLatestSms({
                waitForSingleSmsOptions: {
                    phoneNumberId: this.phoneNumberId,
                    unreadOnly: true,
                    timeout: 30_000,
            // extract the confirmation code from the SMS body
            .then(sms => /([0-9]{6})$/.exec(sms.body!!)!![1])
            // fill out the confirmation form and submit
            .then(code => {
    // fill out sign in form
    it("04 - can sign in with confirmed account", function () {
        // use the email address and a test password
        // click the submit button
    // can see authorized welcome screen
    it("05 - can see welcome screen", function () {
        // click sign up and see welcome
        cy.get("h1").should("contain", "Welcome");