Comparing Mink  Behat drivers for making JS tests

To work with Behat php Mink library is used in Symfony 2. Behat uses a default goutte driver for all tests. This driver works pretty quickly, but it does not support Javascript.

Goutte is a so-called headless browser. Such browsers send real http requests and parse the server's response. They are very simple to use and to configure and it is quite easy to write such a browser as a console application.

The disadvantage of the majority of headless browser is the inability to perform Javascript, and especially AJAX.

To test the pages with JS functionality we mostly need so-called «browser controllers», which are able to run our tests in real browsers. There are also headless browsers capable of executing Javascript.

We now turn to examples. Let’s consider the work with controllers on the example of Selenium2Driver, and as an example of a driver for a headless browser, we’ll select ZombieDriver, which controls the Zombie.js browser. This browser works on node.js.

Selenium2Driver

Installation:

Download Selenium server from here: http://seleniumhq.org/download/ Run it as a hub:

java -jar selenium-server-standalone-2.25.0.jar -role hub

Run it on the computer where the tests will be performed:

java -jar selenium-server-standalone-2.25.0.jar -role node -hub http://127.0.0.1:4444/grid/register -browser
browserName=firefox,version=10,maxInstances=1

Installation of driver for Symfony: https://github.com/Behat/MinkSelenium2Drive

Edit config in Behat.yml:

default:
    extensions:
        Behat\Symfony2Extension\Extension:
            mink_driver: true
            kernel:
                env: test
                debug: true
        Behat\MinkExtension\Extension:
            base_url: 'http://SITE_URL/'
            selenium2:
              wd_host: 'http://127.0.0.1:4444/wd/hub'
              capabilities: { "browser": "firefox", "browserVersion": "10", "browserName": "firefox", "version": "10"}
            default_session: 'symfony2'
    paths:
        features:  features

Use:

To run the test using Selenium2Driver, we should add to it an annotation: @mink:selenium2

Disadvantages:

It does not support status codes (response status code).

ZombieDriver

Installation:

To use this driver, you will need to install node.js and zombie.js module. Installation process of zombie.js is shown here: http://zombie.labnotes.org/#Infection

Driver Installation: https://github.com/Behat/MinkZombieDriver

Edit of config in Behat.yml:

default:
    extensions:
        Behat\Symfony2Extension\Extension:
            mink_driver: true
            kernel:
                env: test
                debug: true
        Behat\MinkExtension\Extension:
            base_url: 'http://SITE_URL/'
            zombie: ~
            default_session: 'symfony2'
    paths:
        features:  features

Use:

To run the test using ZombieDriver, it is necessary to add an annotation: @mink:zombie

Disadvantages:

Zombie.js does not run tests in a particular browser. It emulates work of browser on its own (Javascript is performed using V8 in node.js, parsing of pages is performed using JSDOM and https://github.com/aredridel/html5). Therefore it is impossible to test any needed version of a specific browser.

Features Of Use Of The Above Drivers

In features with AJAX requests, you must first use the wait () method from any Session existing in Mink class. Let’s consider as an example, a feature, in which we need to click on the DOM element that is loaded with AJAX.

    /**
     * @When /^I press something by class "([^"]*)"$/
     */
    public function iPressSomethingByClass($class)
    {
        $class = ".".$class;
        $jsCond = "$('".$class."').length > 0";
        $this->getSession()->wait(5000, $jsCond);
        $this->getSession()->getPage()->find("css", $class)->click();
    }

Otherwise, Mink can click on an item still before it appears.

Conclusion

Selenium2Driver and ZombieDriver perfectly cope with the task of testing pages with Javascript. But among these two drivers personally I prefer Selenium2, for it allows making tests in a particular browser.