Testing JS apps with behat

These days PHP is mainly used to deliver API’s that feed a front end application rather than server side rendered web apps. But that does not mean you necessarily have to give up on the tools you love such as Behat. Here are a few ways to get solid automated testing out of behat:

Spin function:

The backbone of automated testing suites when it comes to JavaScript rendered web apps is the spin function. Use it to to tell behat to keep trying an action until X seconds before giving up. This makes up for any loading delays and transitions that JavaScript may have to go through

public function spin($callable, $waitSeconds = 5, $failureMessage = '')
    for ($i = 0; $i < $waitSeconds; $i++)
        try {
            if ($element = $lambda($this)) {
                return $element;
        } catch (Exception $e) {
            if ($failureMessage) {
                $failureMessage .= PHP_EOL;
            $failureMessage .= 'Error: ' . $e->getMessage();

        usleep(500000); // wait for half a second

    throw new LogicException($failureMessage);

You can use this in any find call on the page like so:

$menuElement = $this->getPage()->find('css', '#main-menu');
... // Operations on menuElement.

// Above re-written like so:
$menuElement = $this->spin(function($context) {
    return $context->getPage()->find('css', '#main-menu');

The above find will be called about 10 times in a span of 5 seconds and fail after. If it finds the element #main-menu anytime in between it will return that response.

You can make a few variations of the spin call such as spinUntilElementFound and spinUntilElementVisible.

Behat fail aid:

Install and configure the genesis/behat-fail-aid extension and enable JS tracking to get the most out of JS testing https://github.com/forceedge01/behat-fail-aid#tracking-js-errorslogs.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *