added support for automatic show on failures
This commit is contained in:
@@ -2,12 +2,8 @@
|
||||
|
||||
namespace Behat\MinkExtension\Context\Initializer;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
use Behat\Behat\Context\Initializer\InitializerInterface,
|
||||
Behat\Behat\Context\ContextInterface,
|
||||
Behat\Behat\Event\ScenarioEvent,
|
||||
Behat\Behat\Event\OutlineEvent;
|
||||
Behat\Behat\Context\ContextInterface;
|
||||
|
||||
use Behat\Mink\Mink;
|
||||
|
||||
@@ -27,7 +23,7 @@ use Behat\MinkExtension\Context\MinkAwareInterface;
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class MinkAwareInitializer implements InitializerInterface, EventSubscriberInterface
|
||||
class MinkAwareInitializer implements InitializerInterface
|
||||
{
|
||||
private $mink;
|
||||
private $parameters;
|
||||
@@ -44,33 +40,6 @@ class MinkAwareInitializer implements InitializerInterface, EventSubscriberInter
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of event names this subscriber wants to listen to.
|
||||
*
|
||||
* The array keys are event names and the value can be:
|
||||
*
|
||||
* * The method name to call (priority defaults to 0)
|
||||
* * An array composed of the method name to call and the priority
|
||||
* * An array of arrays composed of the method names to call and respective
|
||||
* priorities, or 0 if unset
|
||||
*
|
||||
* For instance:
|
||||
*
|
||||
* * array('eventName' => 'methodName')
|
||||
* * array('eventName' => array('methodName', $priority))
|
||||
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
|
||||
*
|
||||
* @return array The event names to listen to
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
'beforeScenario' => array('prepareDefaultMinkSession', 10),
|
||||
'beforeOutline' => array('prepareDefaultMinkSession', 10),
|
||||
'afterSuite' => array('tearDownMinkSessions', -10)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if initializer supports provided context.
|
||||
*
|
||||
@@ -106,47 +75,4 @@ class MinkAwareInitializer implements InitializerInterface, EventSubscriberInter
|
||||
$context->setMink($this->mink);
|
||||
$context->setMinkParameters($this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures default Mink session before each scenario.
|
||||
* Configuration is based on provided scenario tags:
|
||||
*
|
||||
* `@javascript` tagged scenarios will get `javascript_session` as default session
|
||||
* `@mink:CUSTOM_NAME tagged scenarios will get `CUSTOM_NAME` as default session
|
||||
* Other scenarios get `default_session` as default session
|
||||
*
|
||||
* `@insulated` tag will cause Mink to stop current sessions before scenario
|
||||
* instead of just soft-resetting them
|
||||
*
|
||||
* @param ScenarioEvent|OutlineEvent $event
|
||||
*/
|
||||
public function prepareDefaultMinkSession($event)
|
||||
{
|
||||
$scenario = $event instanceof ScenarioEvent ? $event->getScenario() : $event->getOutline();
|
||||
$session = $this->parameters['default_session'];
|
||||
|
||||
foreach ($scenario->getTags() as $tag) {
|
||||
if ('javascript' === $tag) {
|
||||
$session = $this->parameters['javascript_session'];
|
||||
} elseif (preg_match('/^mink\:(.+)/', $tag, $matches)) {
|
||||
$session = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
if ($scenario->hasTag('insulated')) {
|
||||
$this->mink->stopSessions();
|
||||
} else {
|
||||
$this->mink->resetSessions();
|
||||
}
|
||||
|
||||
$this->mink->setDefaultSessionName($session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops all started Mink sessions.
|
||||
*/
|
||||
public function tearDownMinkSessions()
|
||||
{
|
||||
$this->mink->stopSessions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +114,10 @@ class Extension implements ExtensionInterface
|
||||
$minkReflection = new \ReflectionClass('Behat\Mink\Mink');
|
||||
$minkLibPath = realpath(dirname($minkReflection->getFilename()) . '/../../../');
|
||||
$container->setParameter('mink.paths.lib', $minkLibPath);
|
||||
|
||||
if ($config['show_auto']) {
|
||||
$loader->load('failure_show_listener.xml');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,6 +140,9 @@ class Extension implements ExtensionInterface
|
||||
scalarNode('files_path')->
|
||||
defaultValue(isset($config['files_path']) ? $config['files_path'] : null)->
|
||||
end()->
|
||||
booleanNode('show_auto')->
|
||||
defaultValue(false)->
|
||||
end()->
|
||||
scalarNode('show_cmd')->
|
||||
defaultValue(isset($config['show_cmd']) ? $config['show_cmd'] : null)->
|
||||
end()->
|
||||
|
||||
91
src/Behat/MinkExtension/Listener/FailureShowListener.php
Normal file
91
src/Behat/MinkExtension/Listener/FailureShowListener.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Behat\MinkExtension\Listener;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
use Behat\Behat\Event\StepEvent;
|
||||
|
||||
use Behat\Mink\Mink;
|
||||
|
||||
/*
|
||||
* This file is part of the Behat\MinkExtension.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Failed step response show listener.
|
||||
* Listens to failed Behat steps and shows last response in a browser.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class FailureShowListener implements EventSubscriberInterface
|
||||
{
|
||||
private $mink;
|
||||
private $parameters;
|
||||
|
||||
/**
|
||||
* Initializes initializer.
|
||||
*
|
||||
* @param Mink $mink
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function __construct(Mink $mink, array $parameters)
|
||||
{
|
||||
$this->mink = $mink;
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of event names this subscriber wants to listen to.
|
||||
*
|
||||
* The array keys are event names and the value can be:
|
||||
*
|
||||
* * The method name to call (priority defaults to 0)
|
||||
* * An array composed of the method name to call and the priority
|
||||
* * An array of arrays composed of the method names to call and respective
|
||||
* priorities, or 0 if unset
|
||||
*
|
||||
* For instance:
|
||||
*
|
||||
* * array('eventName' => 'methodName')
|
||||
* * array('eventName' => array('methodName', $priority))
|
||||
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
|
||||
*
|
||||
* @return array The event names to listen to
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
'afterStep' => array('showFailedStepResponse', -10)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows last response of failed step with preconfigured command.
|
||||
* Configuration is based on `behat.yml`:
|
||||
*
|
||||
* `show_auto` enable this listener (default to false)
|
||||
* `show_cmd` command to run (`open %s` to open default browser on Mac)
|
||||
* `show_tmp_dir` folder where to store temp files (default is system temp)
|
||||
*
|
||||
* @param StepEvent $event
|
||||
*/
|
||||
public function showFailedStepResponse($event)
|
||||
{
|
||||
if (StepEvent::FAILED !== $event->getResult()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null === $this->parameters['show_cmd']) {
|
||||
throw new \RuntimeException('Set "show_cmd" parameter in behat.yml to be able to open page in browser (ex.: "show_cmd: open %s")');
|
||||
}
|
||||
|
||||
$filename = rtrim($this->parameters['show_tmp_dir'], DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.uniqid().'.html';
|
||||
file_put_contents($filename, $this->mink->getSession()->getPage()->getContent());
|
||||
system(sprintf($this->parameters['show_cmd'], escapeshellarg($filename)));
|
||||
}
|
||||
}
|
||||
112
src/Behat/MinkExtension/Listener/SessionsListener.php
Normal file
112
src/Behat/MinkExtension/Listener/SessionsListener.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace Behat\MinkExtension\Listener;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
use Behat\Behat\Event\ScenarioEvent,
|
||||
Behat\Behat\Event\OutlineEvent;
|
||||
|
||||
use Behat\Mink\Mink;
|
||||
|
||||
/*
|
||||
* This file is part of the Behat\MinkExtension.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Mink sessions listener.
|
||||
* Listens Behat events and configures/stops Mink sessions.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class SessionsListener implements EventSubscriberInterface
|
||||
{
|
||||
private $mink;
|
||||
private $parameters;
|
||||
|
||||
/**
|
||||
* Initializes initializer.
|
||||
*
|
||||
* @param Mink $mink
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function __construct(Mink $mink, array $parameters)
|
||||
{
|
||||
$this->mink = $mink;
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of event names this subscriber wants to listen to.
|
||||
*
|
||||
* The array keys are event names and the value can be:
|
||||
*
|
||||
* * The method name to call (priority defaults to 0)
|
||||
* * An array composed of the method name to call and the priority
|
||||
* * An array of arrays composed of the method names to call and respective
|
||||
* priorities, or 0 if unset
|
||||
*
|
||||
* For instance:
|
||||
*
|
||||
* * array('eventName' => 'methodName')
|
||||
* * array('eventName' => array('methodName', $priority))
|
||||
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
|
||||
*
|
||||
* @return array The event names to listen to
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
'beforeScenario' => array('prepareDefaultMinkSession', 10),
|
||||
'beforeOutline' => array('prepareDefaultMinkSession', 10),
|
||||
'afterSuite' => array('tearDownMinkSessions', -10)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures default Mink session before each scenario.
|
||||
* Configuration is based on provided scenario tags:
|
||||
*
|
||||
* `@javascript` tagged scenarios will get `javascript_session` as default session
|
||||
* `@mink:CUSTOM_NAME tagged scenarios will get `CUSTOM_NAME` as default session
|
||||
* Other scenarios get `default_session` as default session
|
||||
*
|
||||
* `@insulated` tag will cause Mink to stop current sessions before scenario
|
||||
* instead of just soft-resetting them
|
||||
*
|
||||
* @param ScenarioEvent|OutlineEvent $event
|
||||
*/
|
||||
public function prepareDefaultMinkSession($event)
|
||||
{
|
||||
$scenario = $event instanceof ScenarioEvent ? $event->getScenario() : $event->getOutline();
|
||||
$session = $this->parameters['default_session'];
|
||||
|
||||
foreach ($scenario->getTags() as $tag) {
|
||||
if ('javascript' === $tag) {
|
||||
$session = $this->parameters['javascript_session'];
|
||||
} elseif (preg_match('/^mink\:(.+)/', $tag, $matches)) {
|
||||
$session = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
if ($scenario->hasTag('insulated')) {
|
||||
$this->mink->stopSessions();
|
||||
} else {
|
||||
$this->mink->resetSessions();
|
||||
}
|
||||
|
||||
$this->mink->setDefaultSessionName($session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops all started Mink sessions.
|
||||
*/
|
||||
public function tearDownMinkSessions()
|
||||
{
|
||||
$this->mink->stopSessions();
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
<parameter key="behat.mink.context.class_guesser.class">Behat\MinkExtension\Context\ClassGuesser\MinkContextClassGuesser</parameter>
|
||||
<parameter key="behat.mink.context.initializer.class">Behat\MinkExtension\Context\Initializer\MinkAwareInitializer</parameter>
|
||||
<parameter key="behat.mink.listener.sessions_listener.class">Behat\MinkExtension\Listener\SessionsListener</parameter>
|
||||
|
||||
<parameter key="behat.mink.default_session">goutte</parameter>
|
||||
<parameter key="behat.mink.javascript_session">selenium2</parameter>
|
||||
@@ -43,6 +44,11 @@
|
||||
<argument type="service" id="behat.mink" />
|
||||
<argument>%behat.mink.parameters%</argument>
|
||||
<tag name="behat.context.initializer" />
|
||||
</service>
|
||||
|
||||
<service id="behat.mink.listener.sessions_listener" class="%behat.mink.listener.sessions_listener.class%">
|
||||
<argument type="service" id="behat.mink" />
|
||||
<argument>%behat.mink.parameters%</argument>
|
||||
<tag name="behat.event_subscriber" priority="0" />
|
||||
</service>
|
||||
|
||||
|
||||
19
src/Behat/MinkExtension/services/failure_show_listener.xml
Normal file
19
src/Behat/MinkExtension/services/failure_show_listener.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" ?>
|
||||
<container xmlns="http://symfony.com/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
<parameters>
|
||||
|
||||
<parameter key="behat.mink.listener.failure_show_listener.class">Behat\MinkExtension\Listener\FailureShowListener</parameter>
|
||||
|
||||
</parameters>
|
||||
<services>
|
||||
|
||||
<service id="behat.mink.listener.failure_show_listener" class="%behat.mink.listener.failure_show_listener.class%">
|
||||
<argument type="service" id="behat.mink" />
|
||||
<argument>%behat.mink.parameters%</argument>
|
||||
<tag name="behat.event_subscriber" priority="0" />
|
||||
</service>
|
||||
|
||||
</services>
|
||||
</container>
|
||||
Reference in New Issue
Block a user