Code Monkey home page Code Monkey logo

codeception-mailtrap's Introduction

Latest Stable Version Total Downloads Latest Unstable Version License Get help on Codementor

Codeception Mailtrap Module

This package provides a Mailtrap module for Codeception.

Installation

You need to add the repository into your composer.json file

    composer require --dev whatdafox/codeception-mailtrap

Setup

You can use this module as any other Codeception module, by adding 'Mailtrap' to the enabled modules in your Codeception suite configurations.

Add Mailtrap to your list of modules

modules:
    enabled: [Filesystem, FunctionalHelper, Db, Mailtrap]

Setup the configuration variables

modules:
    enabled: [Filesystem, FunctionalHelper, Db, Mailtrap]
    config:
        Mailtrap:
            client_id: ADD_YOUR_TOKEN_HERE
            inbox_id: ADD_YOUR_INBOX_NAME_HERE

Update Codeception build

codecept build

You're all set up!

Usage Examples

Waiting for mail to arrive

If your test depends on your application sending an email, you can instruct the test to wait for something to arrive in your configured Mailtrap inbox before proceeding. These methods all have an optional timeout that can be passed as an additional parameter.

// wait for any email to arrive in your inbox...
$I->waitForEmail();

// ...or wait with an optional 10 second timeout (default is 5 seconds)
$I->waitForEmail(10);

You can also wait for emails that match certain conditions.

// wait for an email with the given subject
$I->waitForEmailWithSubject("Subscription Confirmation");

// wait for an email to arrive with the given string in the HTML part of the body
$I->waitForEmailWithTextInHtmlBody("Thanks for joining!");

// wait for an email to arrive with the given string in the text part of the body
$I->waitForEmailWithTextInTextBody("Thanks for joining!");

Confirming email contents

To confirm specific parts of your email, you can instruct the test to fetch the last email received, and run equality assertions on the email details.

The parameters available for checking are those provided by the Mailtrap API /api/v1/inboxes/inbox_id/messages action.

// returns true if all these parameters are exact matches
$I->receiveEmail([
    'subject' => 'Great Savings On Hamburgers',
    'to_email' => '[email protected]',
    'to_name' => 'Kevin Bacon',
    'from_email' => '[email protected]',
    'from_name' => 'Kate From Astronomical Burgers',
]);

There are methods for checking the most common parameters of a message, which may make your test more legible. These methods will look for exact equivalency.

// check last email was sent from the correct address
$I->receiveAnEmailFromEmail('[email protected]');

// check that the sender name is correct
$I->receiveAnEmailFromName('Kate From Astronomical Burgers');

// check email recipient email is correct
$I->receiveAnEmailToEmail('[email protected]');

// check email recipient name is correct
$I->receiveAnEmailToName('Kevin Bacon');

// check email has correct subject
$I->receiveAnEmailWithSubject('Great Savings On Hamburgers');

// will check to see that the email's text body matches the provided string
$I->receiveAnEmailWithTextBody("the email's complete text body");

// will check to see that the email's html body matches the provided string
$I->receiveAnEmailWithHtmlBody("<strong>the email's complete html body</strong>");

You can also check the last received email for partial matches. For example, looking for an occurrence of 'Great Savings' in 'Great Savings on Hamburgers'.

// check the provided string is somewhere in the subject
$I->seeInEmailSubject('Great Savings');

// check the provided string is somewhere in the email's text body
$I->seeInEmailTextBody("subset of text body");

// check the provided string is somewhere in the email's text body
$I->seeInEmailHtmlBody("<strong>subset of html body</strong>");

Checking Attachments

You can check if your has attachments, or a specific number of attachments. If you want to run further checks on the contents of the attachments you'll have to fetch the message, then interact with the Mailtrap API yourself, though.

// check that there are three attachments on the last message
$I->seeAttachments(3);

// check that there is at least 1 attachment on the last message
$I->seeAnAttachment();

Directly fetching emails

If you need to perform more complex tests, you can directly fetch received emails. Messages are returned as instances of Codeception\Module\MailtrapMessage.

// returns the contents of your Mailtrap inbox
$lastMessages = $I->fetchMessages();

// return teh most recent message received
$lastMessage = $I->fetchLastMessage();

// return the five most recent messages received
$last5Messages = $I->fetchLastMessages(5);

codeception-mailtrap's People

Contributors

captbaritone avatar footballencarta avatar foxted avatar le0nardo98 avatar lrobi2014 avatar nook-ru avatar polevaultweb avatar sergeyklay avatar tomkita avatar yepzy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

codeception-mailtrap's Issues

Assert against any email in the mailbox

@foxted what do you think about enhancing the 'see' assertions so we can look in X last emails.

My use case is testing a process that sends 2 emails at the same time, but at the moment I can only see the last message to run assertions against.

So instead of:

public function seeInEmailHtmlBody($expected)
    {
        $email = $this->fetchLastMessage();
        $this->assertContains($expected, $email['html_body'], 'Email body contains HTML');
    }

We do

public function seeInEmailHtmlBody($expected, $numberOfMessages = 1)
    {
        $email = $this->fetchLastMessages(numberOfMessages);
        $this->assertContains($expected, $email['html_body'], 'Email body contains HTML');
    }

This way the default is still the last message but we can look in a range of mails to assert one exists based on certain criteria.

Adding some use examples in the readme

First off, this is such a great library, thank you so much for providing it. I'm doing some testing on a legacy system that fires off a lot of emails, and it's proving to be invaluable for checking that stuff all works as it should.

The only issue I've had so far is that there's no real docs on how to use the library in your tests. I know that it's all pretty self evident if you spend more than a few minutes with it installed, or even give the source code a fleeting glance, but maybe it would make the module a little friendlier if there were a few examples on how it works in the readme.

I know that's a pretty annoying ask, so if it you're ok with it, I'd be happy to write a few use examples and submit as a pull request to the readme.

Thanks again for making this module available.

Client error: 405

I was trying to get this working with my project but getting an error.

GuzzleHttp\Exception\ClientException]
Client error: 405

I set up a new instance and just pulled in this package

composer require whatdafox/codeception-mailtrap
codecept bootstrap
codecept generate:cest acceptance mail

added it config settings to my acceptance.suite.yaml

    - Mailtrap:
        client_id: xxxx
        inbox_id: xxxx

Created simple test

// tests
public function tryToTest(AcceptanceTester $I)
{
    $I->cleanInbox();
}

then ran

codecept run

And I still get the same error as above.

Here is my composer.lock file if that helps: http://bit.ly/1JaMz4j

Codeception not recognize the module

Hi, I'm trying to install and use this module but it seems not work, after the installation procedure I get error messages when I run an acceptance test.

This is my composer.json

} "require-dev": { "codeception/codeception": "^2.3", "whatdafox/codeception-mailtrap": "^1.2" }, "require": { "fzaninotto/faker": "^1.7" } }

This is the acceptance.suite.yml file (*asterisks for privacy):

`actor: AcceptanceTester
modules:
enabled:
- \Helper\Acceptance

modules:
enabled: [Filesystem, FunctionalHelper, Db, Mailtrap]
config:
Mailtrap:
client_id: '********************'
inbox_id: '*******'

paths:
envs: tests/_envs`

I ran the command "codecept build" but it seems that it not added any method, this is the log:

Building Actor classes for suites: acceptance, functional, unit -> AcceptanceTesterActions.php generated successfully. 0 methods added \AcceptanceTester includes modules: \Helper\Acceptance -> FunctionalTesterActions.php generated successfully. 0 methods added \FunctionalTester includes modules: \Helper\Functional -> UnitTesterActions.php generated successfully. 0 methods added \UnitTester includes modules: Asserts, \Helper\Unit

This is my acceptane Cest:

`<?php

use Faker\Factory as FakerFactory;

class UserAccountCest
{
private $faker;
public function __construct()
{
$this->faker = FakerFactory::create('it_IT');
}

public function _before(AcceptanceTester $I)
{
}

public function _after(AcceptanceTester $I)
{
}

// tests
public function checkEmail(AcceptanceTester $I){
	$I->fetchLastMessage();
}

}`

And finally the error that I get:
"[RuntimeException] Call to undefined method AcceptanceTester::fetchLastMessage"

I think that the issue is releated to the "codecept build" command that not add any module methods to the correct class.
Please can you help me?

Thanks
Regards

Umberto

Error with _after() must implement interface Codeception\TestCase

the module works fine but if i use the module in my acceptance tests i get the error:

Argument 1 passed to Codeception\Module\Mailtrap::_after() must implement interface Codeception\TestCase, instance of Codeception\Test\Cept given, called in ...Codeception/Subscriber/Module.php on line 68 and defined

Delay in mail delivery

In some cases, I have a problem with the package only checking the inbox once, and so if there is any delay in delivery, the email may not have arrived by the time it checks for it. Any ideas how to fix this?

Small modifications for Guzzle ~6.0

Hi @foxted
So I included this via composer to use in my testing environment, and I found some tweaks that need to be made for it to work with Guzzle 6:

  1. The way the Client Guzzle object is constructed - I am suggesting:
$this->client = new Client([
            'base_uri'        => $this->baseUrl,
            'version'         => $this->config['version'],
            'headers' => [
                'Api-Token' => $this->config['client_id'],
            ],

        ]);
  1. I don't think the send() and json() should be used anymore
  2. Since these two functions deprecated in Guzzle 6, the calls made to the api need to be adjusted. For example, fetchLastMessage could probably look like:
$messages = $this->client->get("inboxes/{$this->config['inbox_id']}/messages")->getBody();
return $messages;

This returns a json string of the body response.

  1. On the home page - you could update the sample functional.suite.yml to the following:
class_name: FunctionalTester
modules:
    enabled:
        # add framework module here
        - \Helper\Functional
        - Asserts
        - Laravel5:
            environment_file: .env.testing
            cleanup: true
        - Mailtrap:
            client_id: ADD_YOUR_API_TOKEN_HERE
            inbox_id: ADD_YOUR_INBOX_ID_HERE

I'm not sure if these are unique to me, but I am still sharing in case it helps someone else

Inbox ID?

Hi! I'm trying to use your package but I'm not sure of how to configure it, where do I get the inbox ID? Apparently that's not the name of the inbox but I can't find the ID either.

client_id is the API token, right?

Modules Extends import

Hi @foxted,

I update my packages and I see that the test have fail with this error
PHP Fatal error: Class 'Codeception\Module\Module' not found

And I see that you remove the import of the Module in the commit http://bit.ly/2Hc4PRI

Wait until an email has been received for specific recipient

Will it be possible to add functionality to wait for the arrival of an email destined for a specific recipient?

That's my solution:

public function waitForReceiveAnEmailToEmail(string $recipientEmail, int $timeout = 10)
    {
        $condition = function () use ($recipientEmail) {
            $emails = $this->mailer->fetchMessages();
            foreach ($emails as $email) {
                $constraint = Assert::equalTo($recipientEmail);
                if ($constraint->evaluate($email->to_email, '', true)) {
                    return true;
                }
            }
            return false;
        };

        $message = sprintf('Waited for %d secs but no email with recipient %s has arrived', $timeout,
            $recipientEmail);

        $this->mailtrapWait($timeout)->until($condition, $message);
    }

Can fetchLastMessage be a public method?

hello!

I've been using this package (it works great!) but I'd also like to be able to get the full email message in my test (for example to extract part of the email body, etc.) can you please make fetchLastMessage a public method?

Class 'Codeception\Module\Module' not found in vendor/whatdafox/codeception-mailtrap/src/Mailtrap.php on line 33

I've just checked this module with codeception v2.4.1, but i get an error Class 'Codeception\Module\Module' not found in vendor/whatdafox/codeception-mailtrap/src/Mailtrap.php on line 33 when running 'codecept build'
The Mailtrap class uses the namespace Codeception\Module, so the extended codeception abstract Module class without full namespace resolves to Codeception\Module\Module, which does not exist.
Solution

class Mailtrap extends \Codeception\Module
{

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.