Giter VIP home page Giter VIP logo

codeception-mailcatcher-module's Introduction

Codeception MailCatcher Module

Build Status

This module will let you test emails that are sent during your Codeception acceptance tests. It depends upon you having MailCatcher installed on your development server.

It was inspired by the Codeception blog post: Testing Email in PHP. It is currently very simple. Send a pull request or file an issue if you have ideas for more features.

Installation

  1. Add the package to your composer.json:

    composer require --dev captbaritone/mailcatcher-codeception-module

  2. Configure your project to actually send emails through smtp://127.0.0.1:1025 in the test environment

  3. Enable the module in your acceptance.suite.yml:

    modules:
        enabled:
            - MailCatcher
        config:
            MailCatcher:
                url: 'http://127.0.0.1'
                port: '1080'

Optional Configuration

If you need to specify some special options (e.g. SSL verification or authentication headers), you can set all of the allowed Guzzle request options:

class_name: WebGuy
modules:
    enabled:
        - MailCatcher
    config:
        MailCatcher:
            url: 'http://127.0.0.1'
            port: '1080'
            guzzleRequestOptions:
                verify: false
                debug: true
                version: 1.0

Example Usage

<?php

$I->wantTo('Get a password reset email');

// Clear old emails from MailCatcher
$I->resetEmails();

// Reset password
$I->amOnPage('forgotPassword.php');
$I->fillField("input[name='email']", '[email protected]');
$I->click('Submit');
$I->see('Please check your inbox');

$I->seeInLastEmail('Please click this link to reset your password');

Actions

resetEmails

Clears the emails in MailCatcher's list. This prevents seeing emails sent during a previous test. You probably want to do this before you trigger any emails to be sent

Example:

<?php
// Clears all emails
$I->resetEmails();
?>

seeEmailAttachmentCount

Checks expected count of attachments in last email.

Example:

<?php
$I->seeEmailAttachmentCount(1);
?>
  • Param $expectCount

seeAttachmentInLastEmail

Checks that last email contains an attachment with filename.

Example:

<?php
$I->seeAttachmentInLastEmail('image.jpg');
?>
  • Param $filename

seeInLastEmail

Checks that an email contains a value. It searches the full raw text of the email: headers, subject line, and body.

Example:

<?php
$I->seeInLastEmail('Thanks for signing up!');
?>
  • Param $text

seeInLastEmailTo

Checks that the last email sent to an address contains a value. It searches the full raw text of the email: headers, subject line, and body.

This is useful if, for example a page triggers both an email to the new user, and to the administrator.

Example:

<?php
$I->seeInLastEmailTo('[email protected]', 'Thanks for signing up!');
$I->seeInLastEmailTo('[email protected]', 'A new user has signed up!');
?>
  • Param $email
  • Param $text

dontSeeInLastEmail

Checks that an email does NOT contain a value. It searches the full raw text of the email: headers, subject line, and body.

Example:

<?php
$I->dontSeeInLastEmail('Hit me with those laser beams');
?>
  • Param $text

dontSeeInLastEmailTo

Checks that the last email sent to an address does NOT contain a value. It searches the full raw text of the email: headers, subject line, and body.

Example:

<?php
$I->dontSeeInLastEmailTo('[email protected]', 'But shoot it in the right direction');
?>
  • Param $email
  • Param $text

grabAttachmentsFromLastEmail

Grab Attachments From Email

Returns array with the format [ [filename1 => bytes1], [filename2 => bytes2], ...]

Example:

<?php
$attachments = $I->grabAttachmentsFromLastEmail();
?>

grabMatchesFromLastEmail

Extracts an array of matches and sub-matches from the last email based on a regular expression. It searches the full raw text of the email: headers, subject line, and body. The return value is an array like that returned by preg_match().

Example:

<?php
$matches = $I->grabMatchesFromLastEmail('@<strong>(.*)</strong>@');
?>
  • Param $regex

grabFromLastEmail

Extracts a string from the last email based on a regular expression. It searches the full raw text of the email: headers, subject line, and body.

Example:

<?php
$match = $I->grabFromLastEmail('@<strong>(.*)</strong>@');
?>
  • Param $regex

grabUrlsFromLastEmail

Extracts an array of urls from the last email. It searches the full raw body of the email. The return value is an array of strings.

Example:

<?php
$urls = $I->grabUrlsFromLastEmail();
?>

lastMessageFrom

Grab the full email object sent to an address.

Example:

<?php
$email = $I->lastMessageFrom('[email protected]');
$I->assertNotEmpty($email['attachments']);
?>

lastMessage

Grab the full email object from the last email.

Example:

<?php
$email = $I->grabLastEmail();
$I->assertNotEmpty($email['attachments']);
?>

grabMatchesFromLastEmailTo

Extracts an array of matches and sub-matches from the last email to a given address based on a regular expression. It searches the full raw text of the email: headers, subject line, and body. The return value is an array like that returned by preg_match().

Example:

<?php
$matchs = $I->grabMatchesFromLastEmailTo('[email protected]', '@<strong>(.*)</strong>@');
?>
  • Param $email
  • Param $regex

grabFromLastEmailTo

Extracts a string from the last email to a given address based on a regular expression. It searches the full raw text of the email: headers, subject line, and body.

Example:

<?php
$match = $I->grabFromLastEmailTo('[email protected]', '@<strong>(.*)</strong>@');
?>
  • Param $email
  • Param $regex

seeEmailCount

Asserts that a certain number of emails have been sent since the last time resetEmails() was called.

Example:

<?php
$match = $I->seeEmailCount(2);
?>
  • Param $count

License

Released under the same license as Codeception: MIT

codeception-mailcatcher-module's People

Contributors

akireikin avatar andersonamuller avatar andychute avatar antoineaugusti avatar captbaritone avatar cs278 avatar dependabot[bot] avatar dzoeteman avatar falk avatar guillaume-ro-fr avatar jamesking56 avatar margori avatar michaelarnauts avatar mobileka avatar patabugen avatar paulsheldrake avatar rgeraads avatar shaynekasai avatar thinkspill avatar thomaslandauer avatar voku avatar wazum avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

codeception-mailcatcher-module's Issues

Feature request: Add methods to check for sender and recipient(s)

For the upcoming feature to look for the nth message, I propose a new
feature request (will provide a PR):

  • add method seeSenderInLastEmail/seeSenderInNthEmail to check for the correct sender
  • add method seeRecipientInLastEmail/seeRecipientInNthEmail to check for certain recipient(s)

The data is there and could easily be integrated in the \Codeception\Util\Email entity and \Codeception\Module\MailCatcher module.

Non latin email subjects issue

Non latin subjects create a Header like this

Subject: =?UTF-8?B?zpTOv866zrnOvM6uIM61zrvOu863zr3Ouc66z47OvSDPg8+Ezr/OvSA=?= =?UTF-8?B?z4TOr8+EzrvOvw==?=

As a result, seeInLastEmail() is blind for non latin strings in the subject line.

Codeception v4 support breaks backwards compatibility

Due to requiring codeception/module-asserts, backwards compatibility with codeception < v4 has been broken.

Output from composer:

  Problem 1
    - Installation request for captbaritone/mailcatcher-codeception-module dev-master -> satisfiable by captbaritone/mailcatcher-codeception-module[dev-master].
    - Conclusion: remove codeception/codeception 3.1.2
    - Conclusion: don't install codeception/codeception 3.1.2
    - captbaritone/mailcatcher-codeception-module dev-master requires codeception/module-asserts ^1.1 -> satisfiable by codeception/module-asserts[1.1.0, 1.1.1].
    - codeception/module-asserts 1.1.0 conflicts with codeception/codeception[3.1.2].
    - codeception/module-asserts 1.1.1 conflicts with codeception/codeception[3.1.2].
    - Installation request for codeception/codeception (locked at 3.1.2, required as ^3) -> satisfiable by codeception/codeception[3.1.2].

MailCatcher could not be found and loaded

On running codecept.phar build I get the following error:
MailCatcher could not be found and loaded

Not sure what I'm doing wrong. Any ideas?

acceptance.suite.yml looks like this

# Codeception Test Suite Configuration

# suite for acceptance tests.
# perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.

class_name: AcceptanceTester
modules:
    enabled:
        - PhpBrowser
        - AcceptanceHelper
        - MailCatcher
    config:
        PhpBrowser:
            url: 'http://afspraaq.dev'
        MailCatcher:
            url: 'http://localhost'
            port: '1080'

Drop Codeception v2 support

Codeception 2 first released on 2014-06-06 and the version we support, v2.2, was released on 2016-06-03.

I think we've given a significant amount of time now for people to upgrade to Codeception v3 or v4.

Let's drop support for Codeception v2 so that we can focus on support for v3 and v4.

Emails don't always come out in the order they were put in

If you send multiple emails in rapid succession, and then try to read the last email, you may not get the on you actually sent last.

To get around this in the current tests, I've resorted to adding some sleep() calls:

https://github.com/captbaritone/codeception-mailcatcher-module/blob/master/test/tests/acceptance/MailcatcherCest.php#L37-L46

This is actually a limitation of mailcatcher, or perhaps catchmail (the sendmail standin).

I'm thinking about how to best handle this. Ideas?

Quote printable email

Hi there.

I tried to use grabMatchesFromLastEmail method, and I was struggling with regexps. I really couldn't grab anything, event simple text (in cyrillic encoding). Then I realized that the email is encoded like quoted printable format.

So, it worked for me when I changed $email['source'] to quoted_printable_decode($email['source']) in grabMatchesFromEmail method.

Am I wrong and there is any other way to work with emails without thinking about all these "=3D=5B..." symbols?

Current state of this project

Hi everyone,

We have a major issue in trying to support both Codeception v4 and v5.

In Codeception v4, $config has no type:

https://github.com/Codeception/Codeception/blob/18beff367306d66f955add5fa74e590a5210e219/src/Codeception/Module.php#L57

However, in v5 it does:

https://github.com/Codeception/Codeception/blob/667dfa4acde020b4328aa5570818cc8cb305f8c4/src/Codeception/Module.php#L49

We need to extend $config, so how do we do so without causing a PHP fatal error due to not matching the typing of the parent?

@captbaritone appears to have no vested interest to keep this package going, however, I do still use the package myself on a daily basis.

This is currently a major blocker to this project and I am in discussion with @captbaritone to work out how we move forward so for now we can't add Codeception v5 support. I'll continue to keep publishing new releases to drop support for older Codeception versions (v2 and v3) and to merge in changes from the community.

Drop support for Codeception v3

Now that Codeception v5 is released, I think we should stick to supporting only the last 2 major versions of Codeception, v4 and v5.

resetEmails() doesn't work

I have tried putting $I->resetEmails(); in my test method and in the _before() but regardless of where I place it, all emails from previous runs are still present after running my test.

<?php                                                                                                                      
class LoginCest                                                                                                            
{                                                                                                                          
    public function _before(AcceptanceTester $I)                                                                           
    {                                                                                                                      
        $I->resetEmails();                                                                                                 
    }

    public function signUp(AcceptanceTester $I)
    {
        $I->resetEmails();                                               
        $I->fillField('#EmailAddress', '[email protected]');
        $I->fillField('#Password', 'foobar');
        $I->click('#signupBtn');
        $I->wait(1);                                                                                                    
        $I->see('Your account has been created. You can now login.', '#info'); 
        $I->seeInLastEmail('Your account has been created.');
    }
}
?>

Get URL for link labelled X

Feature request

Add a new method that allows the user to specify a link label, of which the method returns the URL that the label is linked to.

e.g. if I have an email with 2 links:

  1. <a href="http://first-link.com">First link</a>
  2. <a href="http://second-link.com">Second link</a>

It would be great if we could do something like: $I->getUrlForLink('Second link') to get the URL from the second link.

Feel free to make the method name anything you like that makes sense.

Test lowest dependencies

We don't currently run tests for lowest dependencies. We should do this in order to make sure we don't break support for the oldest version of Codeception we support.

more than just last email

would be great to be able to find more than just the last email. I've got a process that sends two emails and I need to be able to check the second.

emailFromId converts = in Query String To ANSI characters

When I try to read an email that contains an URL with a query string the first couple characters after equal sign become decoded by quoted_printable_decode(), for example:
Email boy like:

Check the list on page 56 at http://example.com/list.php?page=56

becomes:

Check the list on page 56 at http://example.com/list.php?pageV

Expected:
URLs containing equal character followed by two hexadecimal characters does not translate into ANSI equivalent

problems with guzzle 5.3.1

it breaks in weird way
[GuzzleHttp\Exception\RequestException] cURL error 3: malformed
$I->resetEmails()
#9 vendor/captbaritone/mailcatcher-codeception-module/src/MailCatcher.php:50
#10 Codeception\Module\MailCatcher->resetEmails

while it's not big issue, but it took me sometime to understand
as temporal fix user can

  • edit vendor/captbaritone/mailcatcher-codeception-module/src/MailCatcher.php
    $this->mailcatcher = new \GuzzleHttp\Client(['base_url' => $base_uri]);
    (i.e. change base_uri to base_url )
  • or check what forces particular version of guzzle , in my case one of packages requires guzzle "<6"

Error when running tests. Missing From argument.

2015-01-29 20-07-29 centos vagrant localhost var www opensource codeception-mailcatcher-module test ssh 132x38

The problem occurs when in PHP's mail() function From header is not settled. There are two possible workarounds:

  1. Set sendmail_from in php.ini. By default it is null.
  2. Always pass From header to mail() function.

Guess, the second option is much better. Tests should work correctly without changing default php.ini params.

2.1.0 release not on packagist

The 2.1.0 release did not seem to get updated on packagist - packagist still labels 2.0.0 as latest version available.

Readme instructions reference version 1.*

I think you guys are on version 2 now.

Screen Shot 2019-05-15 at 9 03 27 AM

Thanks for all the work you've done on this project. I really appreciate that it has continued to provide value even after I've stopped writing PHP myself. ❤️

clickInLastEmail() method?

Hi,

thanks for excellent support of this in codeception, but it will be very helpful if there will be a method similar to clickInLstEmail('some selector of a link or somethink')

Mailcatcher could not be found and loaded

I can't seem to figure out why this won't load. I had the module installed and it was working fine recently, now it won't load.

I can bring up MailCatcher in my browser, the url and port are correct in the yml file.

Did something change?

class_name: FunctionalTester
modules:
    enabled: [Filesystem, FunctionalHelper, Laravel4, MailCatcher]
    config:
        MailCatcher:
            url: 'http://localhost'
            port: '1080'

url attribute on messages?

Hey, I've been using this module for a bit and really like it

I have a thought (and a commit) in regards to a user need that came up in other github issues, which is that of exploring/parsing the HTML of the email while testing.

in the issue threads, the headache of parsing html accurately is mentioned as a reason why there hasn't much movement on this.

Why not include the email's HTML preview URL on mailcatcher (for example, http://localhost:1080/messages/1.html) in the message data? Then the tester can simply use a line of code like $tester->amOnPage($msg['url']) to load the emails' HTML into the test browser. From there the full assortment of assertions and helper functions can be brought to bear on the email's content.

here's a commit that illustrates the idea:

agouticreative@075e058

What do you think? Apologies if this is in the code somewhere already and I stared through it, or if there is a fatal flaw to the idea...

Using guzzleRequestOptions did not work with new version

Using guzzleRequestOptions did not work with new version. If you look at the magic method "__call" at guzzle client you can see that you have to call it with an uri and an option array.

$this->mailcatcher->setDefaultOption($option, $value);

causes an execption.

Your tests never use optional parameters. Think this is why you didn't realized it.
Checked your acceptance.yml

best, Michael

Unified interface for testing email

Hi,

I enjoy working with your module. It is very useful for functional/integration testing. However when it comes to acceptance testing it is not enough. For acceptance testing I need to access real email server.

I think it would be useful to create an interface for testing email in the same way codeception uses interface Codeception\Lib\Interfaces\Web for WebDriver, PhpBrowser, Symfony modules and other. And implement this interface for MailCatcher and IMAP.

Example usecase in continuous integration:

  • Unit tests pass
  • Functional tests pass
  • build gets deployed to test server (with 99.99% production settings, including real SMTP)
  • Acceptance tests run - try to register and confirm email
  • delploy

There is already an imap module so it is not necessary to start from scratch https://github.com/AhmedSamy/codeception-smtp-mail
(Which should be able to use IMAP, POP3 and NNTP)

ConnectException

I'm getting a cURL error that can not connect. Am I forgetting to set something up?

[GuzzleHttp\Exception\ConnectException] cURL error 7: Failed to connect to 127.0.0.1 port 1080: Connection refused (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

I've tried to change the door and ip, and it still does not work.

my api.suite.yml:

actor: ApiTester
modules:
    enabled:
        - REST:
            url: http://localhost:3000/my-project/api
            depends: PhpBrowser
            part: Json
        - MailCatcher:
            url: 'http://127.0.0.1'
            port: '1080'

Emails with returns that split text fail seeInEmail assertions

When you have an email with content which has text that is cut off onto a new line, for example:

This is the te=\r\n
xt that I am searching for.

If you assert that you see This is the text that I am searching for then it will fail due to where the return is.

We should be using PHP's quoted_printable_decode but bear in mind that for URL detection this cannot be used (#63)

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.