Email testing with Codeception
Published: 2024-03-25 16:54:19

Hi to all highly respected PHP developers,

Today we're going to talk about email testing with Codeception framework.
It could be testing of a sign-up form, contact form, or just API. But in this example, we're going to focus on UI testing with Codeception. 
Email testing with API is going to be much easier, so we believe you will be able to apply this example to API by yourself.

We're going to learn how to receive emails that were sent from your product straight to your test, retrieve the confirmation code from the received letter, and put it on to code validation page.

If you want to just jump straight to the code example you can find it on GitHub: https://github.com/proxied-mail/codeception-email-testing-example

## Test case details

https://proxiedmail.com/email-playground/index.html
The page that requests email confirmation:

![Index](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ovbr1geqwv7fvbo66hq.png)

https://proxiedmail.com/email-playground/confirmation.html
The page that validates the confirmation code:
![Validation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8msxerrx76154nshajmg.png)


We're going to request the confirmation code on the first one and check validation on the second.


## Setting up Codeception

You can skip this step if you already have Codeception.

To install via Composer, run this in your project's root:

```bash
composer require "codeception/codeception" --dev
```
From now on Codeception (with installed PHPUnit) can be run as:
```bash
php vendor/bin/codecept
```
Initialize your testing environment with

```bash
php vendor/bin/codecept bootstrap
```

Also, you would need to set up the WebDriver to be able to use Selenium:
```yaml
actor: AcceptanceTester
modules:
    enabled:
        - \Codeception\Module\Asserts
        - WebDriver:
            url: http://proxiedmail.com
            browser: chrome
            host: 'selenium-chrome'
            port: 4444
            capabilities:
                goog:chromeOptions:
                    args: [ "--headless" ]
```

Codeception will also suggest you install the additional packages to add support for the selenium. 
In this yaml we're using Selenium that we set up via docker-compose:
```yaml
  selenium-chrome:
    image: selenium/standalone-chrome
    shm_size: 2g
    container_name: selenium-chrome
    networks:
      - pxdmail-codeception-example
```

## Setting up ProxiedMail

Install [proxiedmail-php-client](https://github.com/proxied-mail/proxiedmail-php-client) library via Composer:
```bash
composer require proxiedmail/php-client
```

Then, we need to set up env variables.
I've used .env file to pass API-token to my tests like this:

```
PROXIEDMAIL_API_TOKEN=your-api-token
```

In [Github example repository](https://github.com/proxied-mail/codeception-email-testing-example) it's shown how to organize passing this value straight to the test.
But please pay attention to codeception.yml which allows you to pass the variable from .env to the tests with the following lines:
```yaml
params:
    - .env
PROXIEDMAIL_API_TOKEN: "%PROXIEDMAIL_API_TOKEN%"
```

### Obtaining ProxiedMail Token
To obtain ProxiedMail token please sign up on [ProxiedMail](https://proxiedmail.com/en/signup). After signing up you will see the "API" link in a header or you can also use the following [link](https://proxiedmail.com/en/settings).

## Coding part

After the setup we are finally able to write our email testing code. 
Create your test:
```bash
php vendor/bin/codecept generate:cest Acceptance EmailCode
```

Then, open the created file and write:
```php
<?php

namespace Tests\Acceptance;

use Codeception\Configuration;
use ProxiedMail\Client\Entrypoint\PxdMailApinitializer;
use Tests\Support\AcceptanceTester;
use ProxiedMail\Client\Config\Config;


class EmailCodeCest
{
    public function _before(AcceptanceTester $I)
    {
    }

    public function frontpageWorks(
        AcceptanceTester $I
    ) {
        $proxiedMailApiToken = Configuration::config()['PROXIEDMAIL_API_TOKEN'];
        $config = new Config();
        $config->setApiToken($proxiedMailApiToken);
        $api = PxdMailApinitializer::init($config);
        $proxyEmail = $api->createProxyEmail();


        $I->amOnPage('/email-playground/index.html');
        $I->fillField(['id' => 'name'], 'Tester');
        $I->fillField(['id' => 'email'], $proxyEmail->getProxyAddress());
        $I->executeJS('document.getElementById("submit").click()');
        sleep(3);

        $I->canSee('Check your mailbox');

        $firstEmail = $api->waitUntilFirstEmail($proxyEmail->getId());

        $I->assertSame($firstEmail->getSubject(), 'Code confirmation');
        $text = $firstEmail->getPayload()['stripped-text'];
        //find code after "Your confirmation code is"
        preg_match('/Your confirmation code is ([0-9]+)/', $text, $matches);
        var_dump($text);
        $code = $matches[1];

        $I->amOnPage('/email-playground/confirmation.html');
        //testing negative behaviour
        $I->fillField(['id' => 'confirmation_code'], mt_rand(0000, 9999));
        $I->executeJS('document.getElementById("submit").click()');
        sleep(1);

        $I->canSee('Code is invalid');


        $I->fillField(['id' => 'confirmation_code'], $code);
        $I->executeJS('document.getElementById("submit").click()');
        sleep(3);
        $I->canSee('Code is valid');
    }

}
```


The code is doing the following actions:
1. Fetching the API token from .env
2. Creating a proxy email like abcddd@proxiedmail.com that provides us the ability to see received emails it
3. Going to https://proxiedmail.com/email-playground/index.html
4. Putting email and name to the form and click submit
5. Checking that the form was submitted
6. Going to https://proxiedmail.com/email-playground/confirmation.html
7. Checking the right subject and extracting the confirmation code
8. Testing negative scenario with wrong confirmation code
9. Putting the correct confirmation code, clicking submit, and verifying that it was the right confirmation code.

## Conclusion

We have tested the email confirmation code. The same code might be applied to any API or sign-up UI or anything else yo can think of. Limits only in your imagination.

## ProxiedMail features

ProxiedMail allows you to create proxy emails with:

1. Callbacks to certain URLs.
2. Browsing received emails.
3. Forwarding incoming emails to any email addresses.

All the features you can find in https://github.com/proxied-mail/proxiedmail-php-client.
Also, we have [JS client](https://github.com/proxied-mail/proxiedmail-js-client), [Laravel Client](https://github.com/proxied-mail/laravel-receive-email) and [Cypress plugin](https://github.com/proxied-mail/cypress-test-email).
You're always welcome to check [ProxiedMail docs](https://docs.proxiedmail.com/) and the [website](https://proxiedmail.com).

Additionally, it's great to secure your data. I highly suggest you learn about [ProxiedMail concept](https://proxiedmail.com/en/blog/proxiedmail-concept) in your free time.

## About ProxiedMail + pricing
ProxiedMail is a tool that brings the email experience to a new level because it was built around the privacy first concept that enhances using a unique email each time which makes it a second password, but also allows you more control over your correspondence.

Additionally, it gives you the advantage of moving to another email provider just in a few seconds. Because we have this kind of system we also aim to bring more into the experience of development using emails.

### Pricing
You can create unlimited proxy emails for your tests just for up to 9 USD/year (for now) and also we have a forever/one payment plan that we usually sell for around 25-30 USD depending on your luck.

### Farewell

Thank you for learning about email testing with me today.
I've put a lot of effort into setting up it, especially in terms of Codeception, but hopefully, it is worth it and could help you to make your product better.

Once again: check out [example repository](https://github.com/proxied-mail/codeception-email-testing-example).

Good luck!

Feel free to ask any questions.
Alex, single founder of ProxiedMail.