Skip to content

webino/WebinoDev

Repository files navigation

Webino developer's module
for Zend Framework 2

Build Status Coverage Status Scrutinizer Code Quality Dependency Status
Latest Stable Version Total Downloads Latest Unstable Version License

Module to ease development of the Webino modules.

Features

  • Utility functions
  • Smart dependency injection definition generator (deprecated)
  • DOM testing
  • Mail testing
  • Selenium abstract tests testing
  • Base classes for Selenium WebDriver tests
    • Authentication testing
    • Forms testing
    • Ajax testing
    • Browser screenshots
    • Video debug notifications support
  • Fixed Assetic\Cache\FilesystemCache file permissions with umask

Requirements

  • PHP 7.1
  • ZendFramework 2

Setup

Open terminal and go to your application directory

  1. Use this module only in your development environment
  • Run php composer.phar require webino/webino-dev:dev-develop
  • Add WebinoDev to the enabled modules list
    NOTE: Considering a zf2-skeleton or very similar application.

QuickStart

Utility functions

d();  // var_dump();
dd(); // var_dump();exit;
p();  // print_r();
pd(); // print_r();exit;
pr(); // return print_r();
e();  // throw new \WebinoDev\Exception\DevelopmentException;

Dependency injection definition generator

Create file bin/definition_generator in your module, with following code:

#!/usr/bin/env php
<?php

namespace WebinoExample;

use WebinoDev\Di\Definition\Generator;

// Autoloader
$loader = require __DIR__ . '/../vendor/autoload.php';
$loader->add(__NAMESPACE__, __DIR__ . '/../src');

// Dump DI definition
(new Generator(__DIR__))->compile()->dump();

NOTE: Assuming WebinoExample/bin/ and WebinoExample/vendor/ directories.
NOTE: Use your namespace instead of WebinoExample.

With custom paths, relative to vendor directory:

(new Generator(__DIR__))->compile(['custom/path/1', 'custom/path/2'])->dump();

With ignored paths:

(new Generator(__DIR__))->setIgnore(['regex1', 'regex2', 'etc.'])->compile()->dump();

Selenium WebDriver tests

use WebinoDev\Test\Selenium\AbstractTestCase;

class HomeTest extends AbstractTestCase
{
    public function testHome()
    {
        $this->openOk('page/path');

        $this->clickLink('Link example');

        /**
         * Use following methods to get a page element
         *
         * It's possible to use $this->elementsBy... to get array of elements also.
         */
        $this->elementByClassName('class-name');

        $this->elementByCssSelector('.class-name tagname');

        $this->elementById('test-id');

        $this->elementByLinkText('Test link');

        $this->elementByName('test_name');

        $this->elementByPartialLinkText('Link text too long');

        $this->elementByTagName('tagname');

        $this->elementByXpath('//test/xpath');

        /**
         * Screenshots
         */
        $data = $this->screenshot();
        // or
        $this->attachScreenshot('Example caption');
    }
}

Testing DOM

use WebinoDev\Test\DomTrait;

/**
 * Concrete test trait
 */
class DomTestCase extends \PHPUnit_Framework_TestCase
{
    use DomTrait;

    public function testDom()
    {
        $xhtml = '<html/>';
        $dom   = $this->createDom($xhtml);
        $elm   = $dom->xpath->query('//html')->item(0);
        $this->assertNotNull($elm);
    }
}

Testing authentication

use WebinoDev\Test\Selenium\AbstractAuthenticationTestCase;

class AuthenticationTest extends AbstractAuthenticationTestCase
{
    public function testAuthentication()
    {
        $this->openOk();
        $this->setAuthSuccessLocator('.authentication-success');
        $this->authenticate();
    }
}

or use trait

use WebinoDev\Test\Selenium\AbstractTestCase;

class AuthenticationTest extends AbstractTestCase
{
    use AuthenticationTrait;
}

Testing forms

use WebinoDev\Test\Selenium\AbstractTestCase;

class HomeTest extends AbstractTestCase
{
    public function testHome()
    {
        $this->submitImput('email', '[email protected]');
    
        // or
    
        $this->enterInput('email', '[email protected]', function ($elm) {
            $elm->submit();
        });

        $this->assertInput('email', '[email protected]');

        $this->waitFor(
            function () {
                return $this->elementByClassName('example-success');
            },
            function ($elm) {
                $this->assertSame('example', $elm->text());
            }
        );
    }
}

Testing AJAX

use WebinoDev\Test\Selenium\AbstractTestCase;

class HomeTest extends AbstractTestCase
{
    public function testHome()
    {
        $this->clickAjaxLink();

        // or

        $this->elementByClassName('ajax-btn')->click();

        $this->waitForAjax();
        // or with delay 2 seconds
        $this->waitForAjax(2);

        $result = $this->elementByClassName('ajax-result')->text();
        $this->assertSame('expected ajax result', $result);
    }
}

Testing mail

Supports functional and selenium mail testing.

Functional mail testing

Assumed that mail messages are saved as files to the virtual filesystem tmp/mail directory.

NOTE: Use org\bovigo\vfs\vfsStream::url('root/tmp/mail') for virtual filesystem directory path.

use WebinoDev\Test\Functional\AbstractMailTestCase;

class MailTest extends AbstractMailTestCase
{
    public function testMail()
    {
        // ...

        $mail = $this->readMail();
        $this->assertNotNull($mail);
        $this->assertSame($expectedSubject, $mail->getSubject());
    }
}

or use trait

use WebinoDev\Test\Functional\AbstractTestCase;
use WebinoDev\Test\Functional\MailTrait;

class MailTest extends AbstractTestCase
{
    use MailTrait;

    /**
     * {@inheritDoc}
     */
    protected function setUp()
    {
        $this->setUpMailVfs();
    }
}
Testing mail with Selenium

Assumed that mail messages are saved as files to the tmp/mail directory, relative to the application.

use WebinoDev\Test\Selenium\AbstractMailTestCase;

class MailTest extends AbstractMailTestCase
{
    public function testMail()
    {
        // ...

        $mail = $this->readMail();
        $this->assertNotNull($mail);
        $this->assertSame($expectedSubject, $mail->getSubject());
    }
}

or use trait

use WebinoDev\Test\Selenium\AbstractTestCase;
use WebinoDev\Test\Selenium\MailTrait;

class MailTest extends AbstractTestCase
{
    use MailTrait;

    /**
     * {@inheritDoc}
     */
    protected function setUp()
    {
        parent::setUp();
        $this->setUpMailDir();
    }

    /**
     * {@inheritDoc}
     */
    protected function tearDown()
    {
        parent::tearDown();
        $this->tearDownMailDir();
    }
}

Testing abstract selenium tests

use WebinoDev\Test\Functional\SeleniumTestTrait;

class AbstractSeleniumTestCaseTest extends \PHPUnit_Framework_TestCase
{
    use SeleniumTestTrait;

    protected $object;

    protected function setUp()
    {
        $this->setUpWebDriver();
        $this->object = new SeleniumTestCase;
        $this->object->session = $this->getWebDriverSession();
    }
}

TODO

  • Use Facebook WebDriver instead of Element34
  • Use Nette\Tester instead of PHPUnit as tests runner
  • Docs debug notifies support
  • Upgrade Zend MVC
  • Upgrade Zend Mail

Addendum

Please, if you are interested in this Zend Framework module report any issues and don't hesitate to contribute. We will appreciate any contributions on development of this module.

Issue | Fork | Develop