mailslurp-examples - javascript-cypress-mailslurp-plugin

https://github.com/mailslurp/examples

Table of Contents

javascript-cypress-mailslurp-plugin/tsconfig.json

{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */

    /* Basic Options */
    // "incremental": true,                         /* Enable incremental compilation */
    "target": "es5",                                /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs",                           /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    // "lib": [],                                   /* Specify library files to be included in the compilation. */
    // "allowJs": true,                             /* Allow javascript files to be compiled. */
    // "checkJs": true,                             /* Report errors in .js files. */
    // "jsx": "preserve",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
    // "declaration": true,                         /* Generates corresponding '.d.ts' file. */
    // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
    // "sourceMap": true,                           /* Generates corresponding '.map' file. */
    // "outFile": "./",                             /* Concatenate and emit output to single file. */
    // "outDir": "./",                              /* Redirect output structure to the directory. */
    // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "composite": true,                           /* Enable project compilation */
    // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
    // "removeComments": true,                      /* Do not emit comments to output. */
    // "noEmit": true,                              /* Do not emit outputs. */
    // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
    // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    // "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": true,                                 /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                       /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true,                    /* Enable strict null checks. */
    // "strictFunctionTypes": true,                 /* Enable strict checking of function types. */
    // "strictBindCallApply": true,                 /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
    // "strictPropertyInitialization": true,        /* Enable strict checking of property initialization in classes. */
    // "noImplicitThis": true,                      /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                        /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    // "noUnusedLocals": true,                      /* Report errors on unused locals. */
    // "noUnusedParameters": true,                  /* Report errors on unused parameters. */
    // "noImplicitReturns": true,                   /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true,          /* Report errors for fallthrough cases in switch statement. */
    // "noUncheckedIndexedAccess": true,            /* Include 'undefined' in index signature results */
    // "noPropertyAccessFromIndexSignature": true,  /* Require undeclared properties from index signatures to use element accesses. */

    /* Module Resolution Options */
    // "moduleResolution": "node",                  /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    // "baseUrl": "./",                             /* Base directory to resolve non-absolute module names. */
    // "paths": {},                                 /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                              /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                             /* List of folders to include type definitions from. */
    // "types": [],                                 /* Type declaration files to be included in compilation. */
    // "allowSyntheticDefaultImports": true,        /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    "esModuleInterop": true,                        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    // "preserveSymlinks": true,                    /* Do not resolve the real path of symlinks. */
    // "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */

    /* Source Map Options */
    // "sourceRoot": "",                            /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    // "mapRoot": "",                               /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,                     /* Emit a single file with source maps instead of having a separate file. */
    // "inlineSources": true,                       /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

    /* Experimental Options */
    // "experimentalDecorators": true,              /* Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true,               /* Enables experimental support for emitting type metadata for decorators. */

    /* Advanced Options */
    "skipLibCheck": true,                           /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true        /* Disallow inconsistently-cased references to the same file. */
  }
}

javascript-cypress-mailslurp-plugin/package.json

{
  "name": "javascript-cypress-mailslurp-plugin",
  "version": "1.0.0",
  "description": "Example cypress-mailslurp plugin usage",
  "scripts": {
    "test": "cypress run --headed",
    "dev": "cypress open"
  },
  "author": "",
  "license": "MIT",
  "dependencies": {
    "cypress": "^13.6.2",
    "cypress-mailslurp": "^1.9.0",
    "typescript": "^5.3.3"
  }
}

javascript-cypress-mailslurp-plugin/cypress.config.ts

import { defineConfig } from 'cypress'

export default defineConfig({
  requestTimeout: 30000,
  responseTimeout: 30000,
  defaultCommandTimeout: 30000,
  e2e: {
    // 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)
    },
  },
})

javascript-cypress-mailslurp-plugin/README.tpl.md

# Cypress MailSlurp plugin example
How to use MailSlurp with Cypress JS. Loads a demonstration app, signs up with a new email address, receives confirmation code, extracts code and submits. Sees welcome screen.

## Documentation
- [Cypress Plugin source](https://github.com/mailslurp/cypress-mailslurp)
- [Plugin documentation](https://docs.mailslurp.com/cypress-mailslurp)

## Run tests
`API_KEY=your-api-key make test`

## Example test

{{{<gen_typescript_cypress_plugin_full>}}}

javascript-cypress-mailslurp-plugin/README.md

# Cypress MailSlurp plugin example
How to use MailSlurp with Cypress JS. Loads a demonstration app, signs up with a new email address, receives confirmation code, extracts code and submits. Sees welcome screen.

## Documentation
- [Cypress Plugin source](https://github.com/mailslurp/cypress-mailslurp)
- [Plugin documentation](https://docs.mailslurp.com/cypress-mailslurp)

## Run tests
`API_KEY=your-api-key make test`

## Example test

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

describe("user sign up test with mailslurp plugin", function () {
    //<gen>cypress_plugin_before
    // use cypress-mailslurp plugin to create an email address before test
    before(function () {
        cy.log("Wrap inbox before test")
        return cy.mailslurp()
            .then(mailslurp => mailslurp.createInbox())
            .then(inbox => {
                cy.log(`Inbox id ${inbox.id}`)
                // save inbox id and email address to this (make sure you use function and not arrow syntax)
                cy.wrap(inbox.id).as('inboxId')
                cy.wrap(inbox.emailAddress).as('emailAddress')
            })
    });
    //</gen>
    it("01 - can load the demo application", function () {
        //<gen>cypress_plugin_01
        // get wrapped email address and assert contains a mailslurp email address
        expect(this.emailAddress).to.contain("@mailslurp");
        // visit the demo application
        cy.visit("https://playground.mailslurp.com")
        cy.title().should('contain', 'React App');
        //</gen>
        //<gen>cypress_plugin_02
        cy.then(function () {
            // click sign up and fill out the form
            cy.get("[data-test=sign-in-create-account-link]").click()
            // use the email address and a test password
            cy.get("[name=email]").type(this.emailAddress).trigger('change');
            cy.get("[name=password]").type('test-password').trigger('change');
            // click the submit button
            cy.get("[data-test=sign-up-create-account-button]").click();
            //</gen>
        })
        //<gen>cypress_plugin_03
        cy.then(function () {
            // app will send user an email containing a code, use mailslurp to wait for the latest email
            cy.mailslurp()
                // use inbox id and a timeout of 30 seconds
                .then(mailslurp => mailslurp.waitForLatestEmail(this.inboxId, 30000, true))
                // extract the confirmation code from the email body
                .then(email => /.*verification code is (\d{6}).*/.exec(email.body!!)!![1])
                // fill out the confirmation form and submit
                .then(code => {
                    cy.get("[name=code]").type(code).trigger('change');
                    cy.get("[data-test=confirm-sign-up-confirm-button]").click();
                })
        })
        //</gen>
        //<gen>cypress_plugin_04
        // fill out sign in form
        cy.then( function () {
            // use the email address and a test password
            cy.get("[data-test=username-input]").type(this.emailAddress).trigger('change');
            cy.get("[data-test=sign-in-password-input]").type('test-password').trigger('change');
            // click the submit button
            cy.get("[data-test=sign-in-sign-in-button]").click();
        });
        //</gen>
        //<gen>cypress_plugin_05
        // can see authorized welcome screen
        cy.then(function () {
            // click sign up and fill out the form
            cy.get("h1").should("contain", "Welcome");
        })
        //</gen>
    });
});
```

javascript-cypress-mailslurp-plugin/Makefile

-include ../.env

node_modules:
	npm install

dev: node_modules
	CYPRESS_MAILSLURP_API_KEY=$(API_KEY) DEBUG='ms*' npm run dev

test: node_modules
	CYPRESS_MAILSLURP_API_KEY=$(API_KEY) DEBUG='ms*' npm run test

javascript-cypress-mailslurp-plugin/cypress/support/e2e.js

// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
//<gen>add_cypress_commands
// add to cypress/support/custom.js
import './commands'
import "cypress-mailslurp";
//</gen>


// Alternatively you can use CommonJS syntax:
// require('./commands')

javascript-cypress-mailslurp-plugin/cypress/support/commands.js

// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })

javascript-cypress-mailslurp-plugin/cypress/plugins/index.js

/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

/**
 * @type {Cypress.PluginConfig}
 */
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
  // `on` is used to hook into various events Cypress emits
  // `config` is the resolved Cypress config
}

javascript-cypress-mailslurp-plugin/cypress/fixtures/example.json

{
  "name": "Using fixtures to represent data",
  "email": "hello@cypress.io",
  "body": "Fixtures are a great way to mock data for responses to routes"
}

javascript-cypress-mailslurp-plugin/cypress/e2e/integration-test.cy.ts

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

describe("user sign up test with mailslurp plugin", function () {
    //<gen>cypress_plugin_before
    // use cypress-mailslurp plugin to create an email address before test
    before(function () {
        cy.log("Wrap inbox before test")
        return cy.mailslurp()
            .then(mailslurp => mailslurp.createInbox())
            .then(inbox => {
                cy.log(`Inbox id ${inbox.id}`)
                // save inbox id and email address to this (make sure you use function and not arrow syntax)
                cy.wrap(inbox.id).as('inboxId')
                cy.wrap(inbox.emailAddress).as('emailAddress')
            })
    });
    //</gen>
    it("01 - can load the demo application", function () {
        //<gen>cypress_plugin_01
        // get wrapped email address and assert contains a mailslurp email address
        expect(this.emailAddress).to.contain("@mailslurp");
        // visit the demo application
        cy.visit("https://playground.mailslurp.com")
        cy.title().should('contain', 'React App');
        //</gen>
        //<gen>cypress_plugin_02
        cy.then(function () {
            // click sign up and fill out the form
            cy.get("[data-test=sign-in-create-account-link]").click()
            // use the email address and a test password
            cy.get("[name=email]").type(this.emailAddress).trigger('change');
            cy.get("[name=password]").type('test-password').trigger('change');
            // click the submit button
            cy.get("[data-test=sign-up-create-account-button]").click();
            //</gen>
        })
        //<gen>cypress_plugin_03
        cy.then(function () {
            // app will send user an email containing a code, use mailslurp to wait for the latest email
            cy.mailslurp()
                // use inbox id and a timeout of 30 seconds
                .then(mailslurp => mailslurp.waitForLatestEmail(this.inboxId, 30000, true))
                // extract the confirmation code from the email body
                .then(email => /.*verification code is (\d{6}).*/.exec(email.body!!)!![1])
                // fill out the confirmation form and submit
                .then(code => {
                    cy.get("[name=code]").type(code).trigger('change');
                    cy.get("[data-test=confirm-sign-up-confirm-button]").click();
                })
        })
        //</gen>
        //<gen>cypress_plugin_04
        // fill out sign in form
        cy.then( function () {
            // use the email address and a test password
            cy.get("[data-test=username-input]").type(this.emailAddress).trigger('change');
            cy.get("[data-test=sign-in-password-input]").type('test-password').trigger('change');
            // click the submit button
            cy.get("[data-test=sign-in-sign-in-button]").click();
        });
        //</gen>
        //<gen>cypress_plugin_05
        // can see authorized welcome screen
        cy.then(function () {
            // click sign up and fill out the form
            cy.get("h1").should("contain", "Welcome");
        })
        //</gen>
    });
});

javascript-cypress-mailslurp-plugin/.run/all tests in integration-test.cy.ts.run.xml

<component name="ProjectRunConfigurationManager">
  <configuration default="false" name="all tests in integration-test.cy.ts" type="JavaScriptTestRunnerCypress">
    <node-interpreter value="project" />
    <cypress-package value="$PROJECT_DIR$/node_modules/cypress" />
    <working-dir value="$PROJECT_DIR$" />
    <cypress-options value="--headed" />
    <envs />
    <scope-kind value="TEST_FILE" />
    <test-file value="$PROJECT_DIR$/cypress/e2e/integration-test.cy.ts" />
    <method v="2" />
  </configuration>
</component>