diff --git a/cypress.json b/cypress.json
index 13ef5f17..52122158 100644
--- a/cypress.json
+++ b/cypress.json
@@ -1,3 +1,6 @@
{
- "baseUrl": "https://app.post-prod.lifen.fr"
+ "baseUrl": "https://app.post-prod.lifen.fr",
+ "env": {
+ "MAILOSAUR_API_KEY": "your-key-here"
+ }
}
diff --git a/cypress/integration/lifen-inbox/inbox.spec.js b/cypress/integration/lifen-inbox/inbox.spec.js
index 519d84af..47dd4fbc 100644
--- a/cypress/integration/lifen-inbox/inbox.spec.js
+++ b/cypress/integration/lifen-inbox/inbox.spec.js
@@ -1,24 +1,24 @@
///
context('The login page', () => {
- describe('Test the login page', () => {
+ describe.skip('Test the login page', () => {
it('Access the webpage', function() {
- cy.visit('/');
+ cy.visit('/login');
cy.get('#email').should("have.attr", "type", "email");
cy.get('#password').should("have.attr", "type", "password");
//cy.get('#password').type(mdp);
});
it('Log an invalid email', function() {
- cy.visit('/');
+ cy.visit('/login');
cy.get('#email').type("not an email");
cy.get('#password').type("somepasseword {enter}");
cy.url().should('include', 'login?');
});
it('Log an unexisting user', function() {
- cy.visit('/');
+ cy.visit('/login');
cy.get('#email').type("toto@yopmail.com");
cy.get('#password').type("somepasseword {enter}");
cy.get('#error-message').should("have.class", "alert alert-danger").should("be.visible");
@@ -28,9 +28,17 @@ context('The login page', () => {
describe("It send an SMS", function() {
it('Log the candidate user', function(){
- cy.visit('/login');
+ cy.visit('/');
cy.get('#email').type("candidature-qa@example.org");
cy.get('#password').type("kHwWawhH5ADNuFb");
+ cy.get('#continueButton').click();
+
+ cy.mailosaurGetMessage(serverId, {
+ sentTo: smsNumber
+ }).as('sms');
+
+ cy.get('#challenge_mfa_form_candidate_otp').type('@sms');
+ cy.get('#validateButton').click();
});
});
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index 119ab03f..2f8764cc 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -23,3 +23,4 @@
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+import 'cypress-mailosaur';
\ No newline at end of file
diff --git a/node_modules/cypress-mailosaur/LICENSE b/node_modules/cypress-mailosaur/LICENSE
new file mode 100644
index 00000000..10a8cb16
--- /dev/null
+++ b/node_modules/cypress-mailosaur/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Mailosaur Ltd (https://mailosaur.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/node_modules/cypress-mailosaur/README.md b/node_modules/cypress-mailosaur/README.md
new file mode 100644
index 00000000..f0249e77
--- /dev/null
+++ b/node_modules/cypress-mailosaur/README.md
@@ -0,0 +1,162 @@
+# Mailosaur Cypress Commands
+
+[](https://github.com/mailosaur/cypress-mailosaur/actions)
+
+## Test email and SMS messages with Cypress
+
+Using Cypress and Mailosaur together you can:
+- Test email, with unlimited test email addresses
+- Test SMS messages
+- Capture emails with your very own fake SMTP servers
+
+## What is Mailosaur?
+
+[Mailosaur](https://mailosaur.com) is a service that lets you automate email testing (e.g. email verification, password resets, etc.) and SMS testing (e.g. one-time passwords).
+
+Mailosaur also provides dummy SMTP servers to test with; allowing you to catch email in staging environments - preventing email being sent to customers by mistake.
+
+## How do I test email with Cypress?
+
+Follow these steps to start testing email with Cypress:
+
+### Step 1 - Installation
+
+Install the Mailosaur commands via `npm`:
+
+```sh
+npm install cypress-mailosaur --save-dev
+```
+
+Once downloaded, add the following line to `cypress/support/index.js` to import the commands into your Cypress project:
+
+```js
+require('cypress-mailosaur');
+```
+
+### Step 2 - API Authentication
+
+Mailosaur commands need your Mailosaur API key to work. You can learn about [managing API keys here](https://mailosaur.com/docs/managing-your-account/api-keys/).
+
+#### Option 1: Add API key to `cypress.json`
+
+```
+{
+ "env": {
+ "MAILOSAUR_API_KEY": "your-key-here"
+ }
+}
+```
+
+#### Option 2: Add API key to a `cypress.env.json` file
+
+You can create your own `cypress.env.json` file that Cypress will automatically check. This is useful because if you add `cypress.env.json` to your `.gitignore` file, the values in here can be different for each developer machine.
+
+```
+{
+ "MAILOSAUR_API_KEY": "your-key-here"
+}
+```
+
+#### Option 3: Set API key via a system environment variable
+
+To set the environment variable on your machine, it needs to be prefixed with either `CYPRESS_` or `cypress_`.
+
+```sh
+export CYPRESS_MAILOSAUR_API_KEY=your-key-here
+```
+
+### Step 3 - Write your email test
+
+For this example, we'll navigate to a password reset page, request a new password link (sent via email), and get that email.
+
+Create a new test spec:
+
+```sh
+touch cypress/integration/password-reset.spec.js
+```
+
+Now edit the file to something like this:
+
+```js
+describe('Password reset', () => {
+ const serverId = 'abcd1234'
+ const serverDomain = 'abcd1234.mailosaur.net'
+ const emailAddress = 'password-reset@' + serverDomain
+
+ it('Makes a Password Reset request', () => {
+ cy.visit('https://github.com/password_reset')
+ cy.title().should('equal', 'Forgot your password?')
+ cy.get('#email_field').type(emailAddress)
+ })
+
+ it('Gets Password Reset email from Mailosaur', () => {
+ cy.mailosaurGetMessage(serverId, {
+ sentTo: emailAddress
+ }).then(email => {
+ expect(email.subject).to.equal('Reset your password');
+ passwordResetLink = email.text.links[0].href;
+ })
+ })
+
+ it('Follows the link from the email', () => {
+ const validPassword = 'delighted cheese jolly cloud'
+
+ cy.visit(passwordResetLink)
+ cy.title().should('contain', 'Change your password')
+ cy.get('#password').type(validPassword)
+ cy.get('#password_confirmation').type(validPassword)
+ cy.get('form').submit()
+ })
+})
+```
+
+### Step 4 - Write further test cases
+
+You can test pretty much anything with Mailosaur and Cypress, including:
+
+- [Test the text content of an email](https://mailosaur.com/docs/test-cases/text-content/)
+- [Test links within an email](https://mailosaur.com/docs/test-cases/links/)
+- [Working with email attachments](https://mailosaur.com/docs/test-cases/attachments/)
+- [Handling images and web beacons](https://mailosaur.com/docs/test-cases/images/)
+- [Perform a spam test](https://mailosaur.com/docs/test-cases/spam/)
+
+For more information, check out the full [Mailosaur docs](https://mailosaur.com/docs/frameworks-and-tools/cypress/) for the most up-to-date guides and troubleshooting tips.
+
+## How do I test SMS with Cypress?
+
+Mailosaur Team, Premium, and Ultimate customers can perform SMS tests with Cypress, whilst Trial account users can just ask support to enable this feature to try it out!
+
+SMS testing works in just the same way as email testing above. However rather than dealing with email addresses, you search using phone numbers instead. For example:
+
+```js
+cy.mailosaurGetMessage(serverId, {
+ sentTo: '447555111222'
+}).then(sms => {
+ expect(sms.text.body).to.equal('Your OTP code is: 123456')
+})
+```
+
+## Development
+
+Install all development dependencies:
+
+```sh
+npm i
+```
+
+The test suite requires the following environment variables to be set:
+
+```sh
+export CYPRESS_MAILOSAUR_API_KEY=your_api_key
+export CYPRESS_MAILOSAUR_SERVER=server_id
+```
+
+Run all tests:
+
+```sh
+npm test
+```
+
+## Contacting us
+
+You can get us at [support@mailosaur.com](mailto:support@mailosaur.com)
diff --git a/node_modules/cypress-mailosaur/index.js b/node_modules/cypress-mailosaur/index.js
new file mode 100644
index 00000000..94f25f4e
--- /dev/null
+++ b/node_modules/cypress-mailosaur/index.js
@@ -0,0 +1,5 @@
+/* global Cypress */
+
+const { register } = require("./src/register");
+
+register(Cypress);
diff --git a/node_modules/cypress-mailosaur/package.json b/node_modules/cypress-mailosaur/package.json
new file mode 100644
index 00000000..5f3ba7a9
--- /dev/null
+++ b/node_modules/cypress-mailosaur/package.json
@@ -0,0 +1,118 @@
+{
+ "_from": "cypress-mailosaur",
+ "_id": "cypress-mailosaur@2.3.3",
+ "_inBundle": false,
+ "_integrity": "sha512-Xo3NqXm0kxdozwAdpCgv2bRLgZyMuGaQS7CK7+e8oFQWFaG/e+zamg8KSbi/n2ROSjm5CXh0WFNMHgBYZ8wZjg==",
+ "_location": "/cypress-mailosaur",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "tag",
+ "registry": true,
+ "raw": "cypress-mailosaur",
+ "name": "cypress-mailosaur",
+ "escapedName": "cypress-mailosaur",
+ "rawSpec": "",
+ "saveSpec": null,
+ "fetchSpec": "latest"
+ },
+ "_requiredBy": [
+ "#DEV:/",
+ "#USER"
+ ],
+ "_resolved": "https://registry.npmjs.org/cypress-mailosaur/-/cypress-mailosaur-2.3.3.tgz",
+ "_shasum": "f7d40905e29f042416e3f504e449b8a320405018",
+ "_spec": "cypress-mailosaur",
+ "_where": "/home/simon/Documents/lifen-autotest",
+ "author": {
+ "name": "Mailosaur Ltd"
+ },
+ "bugs": {
+ "url": "https://github.com/mailosaur/mailosaur-node/issues"
+ },
+ "bundleDependencies": false,
+ "deprecated": false,
+ "description": "Extends Cypress' cy commands that let you integrate email and SMS testing into your continuous integration process.",
+ "devDependencies": {
+ "@types/node": "^15.0.3",
+ "babel-eslint": "10.1.0",
+ "coveralls": "3.0.9",
+ "eslint": "6.8.0",
+ "eslint-config-airbnb-base": "^14.1.0",
+ "eslint-plugin-import": "^2.20.1",
+ "eslint-plugin-react": "^7.20.0",
+ "jest": "25.4.0",
+ "sinon": "9.0.2",
+ "typescript": "^4.2.4"
+ },
+ "engines": {
+ "node": ">= v10.0.0"
+ },
+ "eslintConfig": {
+ "extends": [
+ "airbnb-base"
+ ],
+ "env": {
+ "node": true,
+ "mocha": true
+ },
+ "globals": {
+ "Cypress": true,
+ "cy": true,
+ "assert": true
+ },
+ "rules": {
+ "quotes": [
+ 2,
+ "single",
+ {
+ "allowTemplateLiterals": true
+ }
+ ],
+ "consistent-return": 0,
+ "comma-dangle": 0,
+ "max-len": 0,
+ "no-shadow": 0,
+ "class-methods-use-this": 0,
+ "linebreak-style": 0,
+ "arrow-parens": 0,
+ "operator-linebreak": 0,
+ "object-curly-newline": 0,
+ "implicit-arrow-linebreak": 0,
+ "no-else-return": 0,
+ "indent": 0,
+ "lines-between-class-members": 0
+ }
+ },
+ "files": [
+ "src"
+ ],
+ "homepage": "https://github.com/mailosaur/cypress-mailosaur#readme",
+ "keywords": [
+ "cypress",
+ "mailosaur",
+ "email",
+ "sms",
+ "testing",
+ "automation",
+ "testing-tools"
+ ],
+ "license": "MIT",
+ "main": "index.js",
+ "name": "cypress-mailosaur",
+ "peerDependencies": {
+ "cypress": ">= 2.1.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/mailosaur/cypress-mailosaur.git"
+ },
+ "scripts": {
+ "coveralls": "cat ./coverage/lcov.info | coveralls",
+ "lint": "eslint src test/react-app/src test/react-app/cypress",
+ "test": "npm run tsc && cd test/react-app && npm run test:ci",
+ "test:ci": "cd test/react-app && npm i && npm run test:ci",
+ "tsc": "tsc src/mailosaurCommands.d.ts --types node"
+ },
+ "types": "src/mailosaurCommands.d.ts",
+ "version": "2.3.3"
+}
diff --git a/node_modules/cypress-mailosaur/src/mailosaurCommands.d.ts b/node_modules/cypress-mailosaur/src/mailosaurCommands.d.ts
new file mode 100644
index 00000000..d8be8625
--- /dev/null
+++ b/node_modules/cypress-mailosaur/src/mailosaurCommands.d.ts
@@ -0,0 +1,408 @@
+///
+
+/**
+ * @class
+ * Initializes a new instance of the SpamAssassinRule class.
+ * @constructor
+ * @member {number} [score]
+ * @member {string} [rule]
+ * @member {string} [description]
+ */
+export interface SpamAssassinRule {
+ score?: number;
+ rule?: string;
+ description?: string;
+}
+
+/**
+ * @class
+ * Initializes a new instance of the SpamFilterResults class.
+ * @constructor
+ * @member {array} [spamAssassin]
+ */
+export interface SpamFilterResults {
+ spamAssassin?: SpamAssassinRule[];
+}
+
+/**
+ * @class
+ * Initializes a new instance of the SpamAnalysisResult class.
+ * @constructor
+ * @member {object} [spamFilterResults]
+ * @member {array} [spamFilterResults.spamAssassin]
+ * @member {number} [score]
+ */
+export interface SpamAnalysisResult {
+ spamFilterResults?: SpamFilterResults;
+ score?: number;
+}
+
+/**
+ * @class
+ * Initializes a new instance of the MessageAddress class.
+ * @constructor
+ * @member {string} [name] Display name, if one is specified.
+ * @member {string} [email] Email address (applicable to email messages).
+ * @member {string} [phone] Phone number (applicable to SMS messages).
+ */
+export interface MessageAddress {
+ name?: string;
+ email?: string;
+ phone?: string;
+}
+
+/**
+ * @class
+ * Initializes a new instance of the Link class.
+ * @constructor
+ * @member {string} [href]
+ * @member {string} [text]
+ */
+export interface Link {
+ href?: string;
+ text?: string;
+}
+
+/**
+ * @class
+ * Initializes a new instance of the Image class.
+ * @constructor
+ * @member {string} [src]
+ * @member {string} [alt]
+ */
+export interface Image {
+ src?: string;
+ alt?: string;
+}
+
+/**
+ * @class
+ * Initializes a new instance of the MessageContent class.
+ * @constructor
+ * @member {array} [links]
+ * @member {array} [images]
+ * @member {string} [body]
+ */
+export interface MessageContent {
+ links?: Link[];
+ images?: Image[];
+ body?: string;
+}
+
+/**
+ * @class
+ * Initializes a new instance of the Attachment class.
+ * @constructor
+ * @member {uuid} id
+ * @member {string} [contentType]
+ * @member {string} [fileName]
+ * @member {string} [contentId]
+ * @member {number} [length]
+ * @member {string} [url]
+ */
+export interface Attachment {
+ id: string;
+ contentType?: string;
+ fileName?: string;
+ contentId?: string;
+ length?: number;
+ url?: string;
+}
+
+/**
+ * @class
+ * Initializes a new instance of the MessageHeader class.
+ * @constructor
+ * @member {string} [field] Header key.
+ * @member {string} [value] Header value.
+ */
+export interface MessageHeader {
+ field?: string;
+ value?: string;
+}
+
+/**
+ * @class
+ * Initializes a new instance of the Metadata class.
+ * @constructor
+ * Advanced use case content related to the message.
+ *
+ * @member {array} [headers] Email headers.
+ */
+export interface Metadata {
+ headers?: MessageHeader[];
+}
+
+/**
+ * @class
+ * Initializes a new instance of the Message class.
+ * @constructor
+ * @member {uuid} [id] Unique identifier for the message.
+ * @member {array} [from] The sender of the message.
+ * @member {array} [to] The message’s recipient.
+ * @member {array} [cc] Carbon-copied recipients for email messages.
+ * @member {array} [bcc] Blind carbon-copied recipients for email messages.
+ * @member {date} [received] The datetime that this message was received by
+ * Mailosaur.
+ * @member {string} [subject] The message’s subject.
+ * @member {object} [html] Message content that was sent in HTML format.
+ * @member {array} [html.links]
+ * @member {array} [html.images]
+ * @member {string} [html.body]
+ * @member {object} [text] Message content that was sent in plain text format.
+ * @member {array} [text.links]
+ * @member {array} [text.images]
+ * @member {string} [text.body]
+ * @member {array} [attachments] An array of attachment metadata for any
+ * attached files.
+ * @member {object} [metadata]
+ * @member {array} [metadata.headers] Email headers.
+ * @member {string} [server] Identifier for the server in which the message is
+ * located.
+ */
+export interface Message {
+ id?: string;
+ from?: MessageAddress[];
+ to?: MessageAddress[];
+ cc?: MessageAddress[];
+ bcc?: MessageAddress[];
+ received?: Date;
+ subject?: string;
+ html?: MessageContent;
+ text?: MessageContent;
+ attachments?: Attachment[];
+ metadata?: Metadata;
+ server?: string;
+}
+
+/**
+ * @class
+ * Initializes a new instance of the MessageSummary class.
+ * @constructor
+ * @member {uuid} id
+ * @member {string} [server]
+ * @member {array} [rcpt]
+ * @member {array} [from]
+ * @member {array} [to]
+ * @member {array} [cc]
+ * @member {array} [bcc]
+ * @member {date} [received]
+ * @member {string} [subject]
+ * @member {string} [summary]
+ * @member {number} [attachments]
+ */
+export interface MessageSummary {
+ id: string;
+ server?: string;
+ rcpt?: MessageAddress[];
+ from?: MessageAddress[];
+ to?: MessageAddress[];
+ cc?: MessageAddress[];
+ bcc?: MessageAddress[];
+ received?: Date;
+ subject?: string;
+ summary?: string;
+ attachments?: number;
+}
+
+/**
+ * @class
+ * Initializes a new instance of the MessageListResult class.
+ * @constructor
+ * The result of a message listing request.
+ *
+ * @member {array} [items] The individual summaries of each message forming the
+ * result. Summaries are returned sorted by received date, with the most
+ * recently-received messages appearing first.
+ */
+export interface MessageListResult {
+ items?: MessageSummary[];
+}
+
+/**
+ * @class
+ * Initializes a new instance of the SearchCriteria class.
+ * @constructor
+ * @member {string} [sentFrom] The full email address from which the target email
+ * was sent.
+ * @member {string} [sentTo] The full email address to which the target email
+ * was sent.
+ * @member {string} [subject] The value to seek within the target email's
+ * subject line.
+ * @member {string} [body] The value to seek within the target email's HTML or
+ * text body.
+ * @member {string} [match] If set to ALL (default), then only results that match all
+ * specified criteria will be returned. If set to ANY, results that match any of the
+ * specified criteria will be returned.
+ */
+export interface SearchCriteria {
+ sentFrom?: string;
+ sentTo?: string;
+ subject?: string;
+ body?: string;
+ match?: "ALL" | "ANY";
+}
+
+/**
+ * @class
+ * Initializes a new instance of the Server class.
+ * @constructor
+ * @member {string} [id] Unique identifier for the server. Used as username for
+ * SMTP/POP3 authentication.
+ * @member {string} [name] A name used to identify the server.
+ * @member {array} [users] Users (excluding administrators) who have access to
+ * the server.
+ * @member {number} [messages] The number of messages currently in the server.
+ */
+export interface Server {
+ id?: string;
+ name?: string;
+ users?: string[];
+ messages?: number;
+}
+
+/**
+ * @class
+ * Initializes a new instance of the ServerListResult class.
+ * @constructor
+ * The result of a server listing request.
+ *
+ * @member {array} [items] The individual servers forming the result. Servers
+ * are returned sorted by creation date, with the most recently-created server
+ * appearing first.
+ */
+export interface ServerListResult {
+ items?: Server[];
+}
+
+/**
+ * @class
+ * Initializes a new instance of the ServerCreateOptions class.
+ * @constructor
+ * @member {string} [name] A name used to identify the server.
+ */
+export interface ServerCreateOptions {
+ name?: string;
+}
+
+export interface SearchOptions {
+ timeout?: number,
+ receivedAfter?: Date,
+ page?: number,
+ itemsPerPage?: number,
+ suppressError?: boolean
+}
+
+declare global {
+ namespace Cypress {
+ interface Chainable {
+ /**
+ * @summary List all servers
+ *
+ * Returns a list of your virtual SMTP servers. Servers are returned sorted in
+ * alphabetical order.
+ *
+ */
+ mailosaurListServers(
+ ): Cypress.Chainable;
+
+ mailosaurCreateServer(
+ options: ServerCreateOptions
+ ): Cypress.Chainable;
+
+ mailosaurGetServer(
+ serverId: string
+ ): Cypress.Chainable;
+
+ mailosaurGetServerPassword(
+ serverId: string
+ ): Cypress.Chainable;
+
+ mailosaurUpdateServer(
+ server: Server
+ ): Cypress.Chainable;
+
+ mailosaurDeleteServer(
+ serverId: string
+ ): Cypress.Chainable;
+
+ mailosaurDeleteAllMessages(
+ serverId: string
+ ): Cypress.Chainable;
+
+ mailosaurListMessages(
+ serverId: string
+ ): Cypress.Chainable;
+
+ mailosaurCreateMessage(
+ serverId: string
+ ): Cypress.Chainable;
+
+ mailosaurGetMessage(
+ serverId: string,
+ criteria: SearchCriteria,
+ options?: SearchOptions
+ ): Cypress.Chainable;
+
+ mailosaurGetMessageById(
+ messageId: string
+ ): Cypress.Chainable;
+
+ mailosaurSearchMessages(
+ serverId: string,
+ criteria: SearchCriteria,
+ options?: SearchOptions
+ ): Cypress.Chainable;
+
+ mailosaurGetMessagesBySubject(
+ serverId: string,
+ subject: string
+ ): Cypress.Chainable;
+
+ mailosaurGetMessagesByBody(
+ serverId: string,
+ body: string
+ ): Cypress.Chainable;
+
+ mailosaurGetMessagesBySentFrom(
+ serverId: string,
+ sentFrom: string
+ ): Cypress.Chainable;
+
+ mailosaurGetMessagesBySentTo(
+ serverId: string,
+ sentTo: string
+ ): Cypress.Chainable;
+
+ mailosaurDownloadAttachment(
+ attachmentId: string
+ ): Cypress.Chainable;
+
+ mailosaurDownloadMessage(
+ messageId: string
+ ): Cypress.Chainable;
+
+ mailosaurDeleteMessage(
+ messageId: string
+ ): Cypress.Chainable;
+
+ /**
+ * @summary Perform a spam test
+ *
+ * Perform spam testing on the specified email
+ *
+ * @param {string} messageId The identifier of the email to be analyzed.
+ *
+ * @returns {Chainable}
+ */
+ mailosaurGetSpamAnalysis(
+ messageId: string
+ ): Chainable;
+
+ mailosaurGenerateEmailAddress(
+ serverId: string
+ ): Cypress.Chainable;
+ }
+
+ }
+}
diff --git a/node_modules/cypress-mailosaur/src/mailosaurCommands.js b/node_modules/cypress-mailosaur/src/mailosaurCommands.js
new file mode 100644
index 00000000..bde63306
--- /dev/null
+++ b/node_modules/cypress-mailosaur/src/mailosaurCommands.js
@@ -0,0 +1,210 @@
+const Request = require('./request');
+
+class MailosaurCommands {
+ static get cypressCommands() {
+ return [
+ 'mailosaurSetApiKey',
+ 'mailosaurListServers',
+ 'mailosaurCreateServer',
+ 'mailosaurGetServer',
+ 'mailosaurGetServerPassword',
+ 'mailosaurUpdateServer',
+ 'mailosaurDeleteServer',
+ 'mailosaurListMessages',
+ 'mailosaurCreateMessage',
+ 'mailosaurGetMessage',
+ 'mailosaurGetMessageById',
+ 'mailosaurSearchMessages',
+ 'mailosaurGetMessagesBySubject',
+ 'mailosaurGetMessagesByBody',
+ 'mailosaurGetMessagesBySentFrom',
+ 'mailosaurGetMessagesBySentTo',
+ 'mailosaurDeleteMessage',
+ 'mailosaurDeleteAllMessages',
+ 'mailosaurDownloadAttachment',
+ 'mailosaurDownloadMessage',
+ 'mailosaurGetSpamAnalysis',
+ 'mailosaurGenerateEmailAddress'
+ ];
+ }
+
+ constructor() {
+ const defaultApiKey = Cypress.env('MAILOSAUR_API_KEY');
+ this.mailosaurSetApiKey(defaultApiKey);
+ }
+
+ mailosaurSetApiKey(apiKey) {
+ this.request = new Request({ apiKey, baseUrl: Cypress.env('MAILOSAUR_BASE_URL') });
+ }
+
+ mailosaurListServers() {
+ return this.request.get(`api/servers`);
+ }
+
+ mailosaurCreateServer(params) {
+ return this.request.post(`api/servers`, params);
+ }
+
+ mailosaurGetServer(serverId) {
+ return this.request.get(`api/servers/${serverId}`);
+ }
+
+ mailosaurGetServerPassword(serverId) {
+ return this.request.get(`api/servers/${serverId}/password`)
+ .then((result) => (result.value));
+ }
+
+ mailosaurUpdateServer(server) {
+ return this.request.put(`api/servers/${server.id}`, server);
+ }
+
+ mailosaurDeleteServer(serverId) {
+ return this.request.del(`api/servers/${serverId}`);
+ }
+
+ mailosaurDeleteAllMessages(serverId) {
+ return this.request.del(`api/messages?server=${serverId}`);
+ }
+
+ mailosaurListMessages(serverId) {
+ return this.request.get(`api/messages?server=${serverId}`);
+ }
+
+ mailosaurCreateMessage(serverId) {
+ return this.request.post(`api/messages?server=${serverId}`, {});
+ }
+
+ mailosaurGetMessage(server, criteria, options = {}) {
+ // Only return 1 result
+ options.page = 0;
+ options.itemsPerPage = 1;
+
+ // Default timeout to 10s
+ options.timeout = options.timeout || 10000; // eslint-disable-line no-param-reassign
+
+ // Default receivedAfter to 1h
+ options.receivedAfter = options.receivedAfter || new Date(Date.now() - 3600000); // eslint-disable-line no-param-reassign
+
+ return cy.mailosaurSearchMessages(server, criteria, options)
+ .then((result) => (
+ cy.mailosaurGetMessageById(result.items[0].id)
+ ));
+ }
+
+ mailosaurGetMessageById(messageId) {
+ return this.request.get(`api/messages/${messageId}`);
+ }
+
+ mailosaurSearchMessages(serverId, searchCriteria, options = {}) {
+ let pollCount = 0;
+ const startTime = Date.now();
+
+ const qs = {
+ server: serverId,
+ page: options.page,
+ itemsPerPage: options.itemsPerPage,
+ receivedAfter: options.receivedAfter
+ };
+
+ if (!Number.isInteger(options.timeout)) {
+ options.timeout = 0; // eslint-disable-line no-param-reassign
+ }
+
+ if (typeof options.errorOnTimeout !== 'boolean') {
+ options.errorOnTimeout = true; // eslint-disable-line no-param-reassign
+ }
+
+ const fn = (resolve, reject) => () => {
+ const reqOptions = this.request.buildOptions('POST', `api/messages/search`);
+ reqOptions.qs = qs;
+ reqOptions.json = searchCriteria;
+
+ return Cypress.backend('http:request', reqOptions)
+ .timeout(10000)
+ .then((result) => {
+ const { body, status, headers } = result;
+
+ switch (status) {
+ case 200:
+ break;
+ case 400:
+ return reject(new Error(JSON.stringify(result.body)));
+ case 401:
+ return reject(new Error('Cannot authenticate with Mailosaur (401). Please check your API key.'));
+ default:
+ return reject(new Error(`Status: ${status}, Result: ${JSON.stringify(result)}`));
+ }
+
+ if (options.timeout && !body.items.length) {
+ const delayPattern = (headers['x-ms-delay'] || '1000')
+ .split(',')
+ .map(x => parseInt(x, 10));
+
+ const delay = (pollCount >= delayPattern.length) ?
+ delayPattern[delayPattern.length - 1] :
+ delayPattern[pollCount];
+
+ pollCount += 1;
+
+ // Stop if timeout will be exceeded
+ if (((Date.now() - startTime) + delay) > options.timeout) {
+ return (options.errorOnTimeout === false) ?
+ resolve(body) :
+ reject(new Error('No matching messages found in time. By default, only messages received in the last hour are checked (use receivedAfter to override this).'));
+ }
+
+ return setTimeout(fn(resolve, reject), delay);
+ }
+
+ resolve(body);
+ });
+ };
+
+ cy.wrap(new Cypress.Promise((resolve, reject) => {
+ fn(resolve, reject)();
+ }), {
+ log: false,
+ timeout: options.timeout + 10000
+ });
+ }
+
+ mailosaurGetMessagesBySubject(serverId, subject) {
+ return cy.mailosaurSearchMessages(serverId, { subject });
+ }
+
+ mailosaurGetMessagesByBody(serverId, body) {
+ return cy.mailosaurSearchMessages(serverId, { body });
+ }
+
+ mailosaurGetMessagesBySentFrom(serverId, sentFrom) {
+ return cy.mailosaurSearchMessages(serverId, { sentFrom });
+ }
+
+ mailosaurGetMessagesBySentTo(serverId, sentTo) {
+ return cy.mailosaurSearchMessages(serverId, { sentTo });
+ }
+
+ mailosaurDownloadAttachment(attachmentId) {
+ return this.request.get(`api/files/attachments/${attachmentId}`);
+ }
+
+ mailosaurDownloadMessage(messageId) {
+ return this.request.get(`api/files/email/${messageId}`);
+ }
+
+ mailosaurDeleteMessage(messageId) {
+ return this.request.del(`api/messages/${messageId}`);
+ }
+
+ mailosaurGetSpamAnalysis(messageId) {
+ return this.request.get(`api/analysis/spam/${messageId}`);
+ }
+
+ mailosaurGenerateEmailAddress(serverId) {
+ const host = Cypress.env('MAILOSAUR_SMTP_HOST') || 'mailosaur.net';
+ const random = (Math.random() + 1).toString(36).substring(7);
+ return cy.wrap(`${random}@${serverId}.${host}`);
+ }
+}
+
+module.exports = MailosaurCommands;
diff --git a/node_modules/cypress-mailosaur/src/register.js b/node_modules/cypress-mailosaur/src/register.js
new file mode 100644
index 00000000..f7e45fcc
--- /dev/null
+++ b/node_modules/cypress-mailosaur/src/register.js
@@ -0,0 +1,15 @@
+const MailosaurCommands = require('./mailosaurCommands');
+
+const register = (Cypress) => {
+ const mailosaurCommands = new MailosaurCommands();
+ MailosaurCommands.cypressCommands.forEach((commandName) => {
+ Cypress.Commands.add(
+ commandName,
+ mailosaurCommands[commandName].bind(mailosaurCommands)
+ );
+ });
+};
+
+module.exports = {
+ register,
+};
diff --git a/node_modules/cypress-mailosaur/src/request.js b/node_modules/cypress-mailosaur/src/request.js
new file mode 100644
index 00000000..bc7e8733
--- /dev/null
+++ b/node_modules/cypress-mailosaur/src/request.js
@@ -0,0 +1,56 @@
+const pkg = require('../package.json');
+
+/* eslint-disable max-classes-per-file */
+class Request {
+ constructor(options) {
+ this.baseUrl = options.baseUrl || 'https://mailosaur.com/';
+ this.apiKey = options.apiKey;
+ const encodedKey = Buffer.from(`${this.apiKey}:`).toString('base64');
+ this.headers = {
+ Accept: 'application/json',
+ Authorization: `Basic ${encodedKey}`,
+ 'User-Agent': `cypress-mailosaur/${pkg.version}`
+ };
+ }
+
+ buildOptions(method, path) {
+ if (!this.apiKey) {
+ // CYPRESS_ prefix necessary per https://docs.cypress.io/guides/guides/environment-variables.html#Option-3-CYPRESS
+ throw new Error('You must set the CYPRESS_MAILOSAUR_API_KEY environment variable to use the Mailosaur plugin.');
+ }
+
+ return {
+ method,
+ url: `${this.baseUrl}${path}`,
+ headers: {
+ Accept: this.headers.Accept,
+ Authorization: this.headers.Authorization,
+ 'User-Agent': this.headers['User-Agent']
+ }
+ };
+ }
+
+ request(method, path, body) {
+ const options = this.buildOptions(method, path);
+ options.body = body || undefined;
+ return cy.request(options).its('body');
+ }
+
+ get(path) {
+ return this.request('GET', path);
+ }
+
+ post(path, body) {
+ return this.request('POST', path, body);
+ }
+
+ put(path, body) {
+ return this.request('PUT', path, body);
+ }
+
+ del(path) {
+ return this.request('DELETE', path);
+ }
+}
+
+module.exports = Request;
diff --git a/package-lock.json b/package-lock.json
index 937609dc..9a813fe6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2514,6 +2514,12 @@
}
}
},
+ "cypress-mailosaur": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/cypress-mailosaur/-/cypress-mailosaur-2.3.3.tgz",
+ "integrity": "sha512-Xo3NqXm0kxdozwAdpCgv2bRLgZyMuGaQS7CK7+e8oFQWFaG/e+zamg8KSbi/n2ROSjm5CXh0WFNMHgBYZ8wZjg==",
+ "dev": true
+ },
"d": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
diff --git a/package.json b/package.json
index 62218bf8..78e7c58c 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,8 @@
"cypress": "^8.3.1"
},
"devDependencies": {
- "cypress-cucumber-preprocessor": "^4.2.0"
+ "cypress-cucumber-preprocessor": "^4.2.0",
+ "cypress-mailosaur": "^2.3.3"
},
"scripts": {
"test": "cypress open"