Conditional intercepting of redirections with Behat and Mink

In behat documentation, the topic of intercepting redirections is discussed in the context of using the profiler to test some of the features that hit specific browsers.

The solution proposed there has a specific drawback: it only works when you are trying to test using either goutte or symfony driver.

However, if some of the features you want to test using different driver too – like selenium2, that supports redirections, but does not allow to intercept them – you have to try different approach.

The original solution is using two-step process of doing it. At first, it checks whether the driver supports intercepting redirections and disables them if so. Then after the interception, it redirects and continues to the next step.

I figured out that I can modify the original bootstrap to not throw an exception when I’m using selenium2 driver but return false instead:

<?php
 
use Behat\BehatBundle\Context\MinkContext;
use Behat\Behat\Context\Step;
use Behat\Mink\Exception\UnsupportedDriverActionException;
use Behat\Mink\Driver\GoutteDriver;
use Behat\Mink\Driver\Selenium2Driver;
 
/**
 * Feature context.
 */
class FeatureContext extends MinkContext
{
    public function canIntercept()
    {
        $driver = $this->getSession()->getDriver();
        if ($driver instanceof GoutteDriver)
        {
            return true;
        }
        else if ($driver instanceof Selenium2Driver)
        {
            return false;
        }
 
        throw new UnsupportedDriverActionException(
            'You need to tag the scenario with '.
            '"@mink:goutte" or "@mink:symfony". '.
            'Intercepting the redirections is not '.
            'supported by %s', $driver
        );
    }
}

Then, when implementing steps I check for the return value:

/**
 * @Given /^(.*) without redirection$/
 */
public function theRedirectionsAreIntercepted($step)
{
    if ($this->canIntercept())
    {
        $this->getSession()
             ->getDriver()
             ->getClient()
             ->followRedirects(false);
    }
 
    return new Step\Given($step);
}
 
/**
 * @When /^I follow the redirection$/
 * @Then /^I should be redirected$/
 */
public function iFollowTheRedirection($url)
{
    if ($this->canIntercept())
    {
        $client = $this->getSession()
                       ->getDriver()
                       ->getClient();
                       ->followRedirects(true);
                       ->followRedirect();
    }
}

This approach allows me to change driver sessions not having to worry that one of the features will throw an exception when dealing with redirection.

Leave a Reply