Merge pull request #136 from stof/default_session_per_suite
Added the possibility to define the default session per suite
This commit is contained in:
@@ -165,6 +165,17 @@ and on scenario tags:
|
|||||||
* A scenario tagged with ``@javascript`` will use the javascript session as default session;
|
* A scenario tagged with ``@javascript`` will use the javascript session as default session;
|
||||||
* Other scenarios will use the default session.
|
* Other scenarios will use the default session.
|
||||||
|
|
||||||
|
The default session and the default javascript session can also be configured for
|
||||||
|
each suite:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
default:
|
||||||
|
suites:
|
||||||
|
first:
|
||||||
|
mink_session: foo
|
||||||
|
mink_javascript_session: sahi
|
||||||
|
|
||||||
If it is not configured explicitly, the javascript session is set to the first
|
If it is not configured explicitly, the javascript session is set to the first
|
||||||
session using a javascript driver in the order of the configuration (it would
|
session using a javascript driver in the order of the configuration (it would
|
||||||
be ``first_session`` in the example above as ``selenium2`` supports Javascript).
|
be ``first_session`` in the example above as ``selenium2`` supports Javascript).
|
||||||
|
|||||||
@@ -7,17 +7,23 @@ use Behat\Gherkin\Node\FeatureNode;
|
|||||||
use Behat\Gherkin\Node\ScenarioNode;
|
use Behat\Gherkin\Node\ScenarioNode;
|
||||||
use Behat\Mink\Mink;
|
use Behat\Mink\Mink;
|
||||||
use Behat\Testwork\ServiceContainer\Exception\ProcessingException;
|
use Behat\Testwork\ServiceContainer\Exception\ProcessingException;
|
||||||
|
use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
|
||||||
|
use Behat\Testwork\Suite\Suite;
|
||||||
use PhpSpec\ObjectBehavior;
|
use PhpSpec\ObjectBehavior;
|
||||||
|
|
||||||
class SessionsListenerSpec extends ObjectBehavior
|
class SessionsListenerSpec extends ObjectBehavior
|
||||||
{
|
{
|
||||||
function let(Mink $mink, ScenarioTested $event, FeatureNode $feature, ScenarioNode $scenario)
|
function let(Mink $mink, ScenarioTested $event, FeatureNode $feature, ScenarioNode $scenario, Suite $suite)
|
||||||
{
|
{
|
||||||
$this->beConstructedWith($mink, 'goutte', 'selenium2');
|
$this->beConstructedWith($mink, 'goutte', 'selenium2', array('selenium2', 'sahi'));
|
||||||
|
|
||||||
|
$event->getSuite()->willReturn($suite);
|
||||||
$event->getFeature()->willReturn($feature);
|
$event->getFeature()->willReturn($feature);
|
||||||
$event->getScenario()->willReturn($scenario);
|
$event->getScenario()->willReturn($scenario);
|
||||||
|
|
||||||
|
$suite->hasSetting('mink_session')->willReturn(false);
|
||||||
|
$suite->getName()->willReturn('default');
|
||||||
|
|
||||||
$feature->hasTag('insulated')->willReturn(false);
|
$feature->hasTag('insulated')->willReturn(false);
|
||||||
$feature->getTags()->willReturn(array());
|
$feature->getTags()->willReturn(array());
|
||||||
$scenario->hasTag('insulated')->willReturn(false);
|
$scenario->hasTag('insulated')->willReturn(false);
|
||||||
@@ -37,8 +43,29 @@ class SessionsListenerSpec extends ObjectBehavior
|
|||||||
$this->prepareDefaultMinkSession($event);
|
$this->prepareDefaultMinkSession($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_switches_to_the_javascript_session_for_tagged_scenarios($event, $mink, $scenario)
|
function it_supports_changing_the_default_session_per_suite($event, $mink, $suite)
|
||||||
{
|
{
|
||||||
|
$suite->hasSetting('mink_session')->willReturn(true);
|
||||||
|
$suite->getSetting('mink_session')->willReturn('test');
|
||||||
|
|
||||||
|
$mink->resetSessions()->shouldBeCalled();
|
||||||
|
$mink->setDefaultSessionName('test')->shouldBeCalled();
|
||||||
|
|
||||||
|
$this->prepareDefaultMinkSession($event);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_fails_for_non_string_default_suite_session($event, $suite)
|
||||||
|
{
|
||||||
|
$suite->hasSetting('mink_session')->willReturn(true);
|
||||||
|
$suite->getSetting('mink_session')->willReturn(array());
|
||||||
|
|
||||||
|
$this->shouldThrow(new SuiteConfigurationException('`mink_session` setting of the "default" suite is expected to be a string, array given.', 'default'))
|
||||||
|
->duringPrepareDefaultMinkSession($event);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_switches_to_the_javascript_session_for_tagged_scenarios($event, $mink, $scenario, $suite)
|
||||||
|
{
|
||||||
|
$suite->hasSetting('mink_javascript_session')->willReturn(false);
|
||||||
$scenario->getTags()->willReturn(array('javascript'));
|
$scenario->getTags()->willReturn(array('javascript'));
|
||||||
$mink->resetSessions()->shouldBeCalled();
|
$mink->resetSessions()->shouldBeCalled();
|
||||||
$mink->setDefaultSessionName('selenium2')->shouldBeCalled();
|
$mink->setDefaultSessionName('selenium2')->shouldBeCalled();
|
||||||
@@ -46,8 +73,9 @@ class SessionsListenerSpec extends ObjectBehavior
|
|||||||
$this->prepareDefaultMinkSession($event);
|
$this->prepareDefaultMinkSession($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_switches_to_the_javascript_session_for_tagged_features($event, $mink, $feature)
|
function it_switches_to_the_javascript_session_for_tagged_features($event, $mink, $feature, $suite)
|
||||||
{
|
{
|
||||||
|
$suite->hasSetting('mink_javascript_session')->willReturn(false);
|
||||||
$feature->getTags()->willReturn(array('javascript'));
|
$feature->getTags()->willReturn(array('javascript'));
|
||||||
$mink->resetSessions()->shouldBeCalled();
|
$mink->resetSessions()->shouldBeCalled();
|
||||||
$mink->setDefaultSessionName('selenium2')->shouldBeCalled();
|
$mink->setDefaultSessionName('selenium2')->shouldBeCalled();
|
||||||
@@ -55,8 +83,43 @@ class SessionsListenerSpec extends ObjectBehavior
|
|||||||
$this->prepareDefaultMinkSession($event);
|
$this->prepareDefaultMinkSession($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_fails_when_the_javascript_session_is_used_but_not_defined($event, $mink, $feature)
|
function it_supports_changing_the_default_javascript_session_per_suite($event, $mink, $scenario, $suite)
|
||||||
{
|
{
|
||||||
|
$suite->hasSetting('mink_javascript_session')->willReturn(true);
|
||||||
|
$suite->getSetting('mink_javascript_session')->willReturn('sahi');
|
||||||
|
|
||||||
|
$scenario->getTags()->willReturn(array('javascript'));
|
||||||
|
$mink->resetSessions()->shouldBeCalled();
|
||||||
|
$mink->setDefaultSessionName('sahi')->shouldBeCalled();
|
||||||
|
|
||||||
|
$this->prepareDefaultMinkSession($event);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_fails_for_non_string_javascript_suite_session($event, $scenario, $suite)
|
||||||
|
{
|
||||||
|
$suite->hasSetting('mink_javascript_session')->willReturn(true);
|
||||||
|
$suite->getSetting('mink_javascript_session')->willReturn(array());
|
||||||
|
|
||||||
|
$scenario->getTags()->willReturn(array('javascript'));
|
||||||
|
|
||||||
|
$this->shouldThrow(new SuiteConfigurationException('`mink_javascript_session` setting of the "default" suite is expected to be a string, array given.', 'default'))
|
||||||
|
->duringPrepareDefaultMinkSession($event);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_fails_for_invalid_javascript_suite_session($event, $scenario, $suite)
|
||||||
|
{
|
||||||
|
$suite->hasSetting('mink_javascript_session')->willReturn(true);
|
||||||
|
$suite->getSetting('mink_javascript_session')->willReturn('test');
|
||||||
|
|
||||||
|
$scenario->getTags()->willReturn(array('javascript'));
|
||||||
|
|
||||||
|
$this->shouldThrow(new SuiteConfigurationException('`mink_javascript_session` setting of the "default" suite is not a javascript session. test given but expected one of selenium2, sahi.', 'default'))
|
||||||
|
->duringPrepareDefaultMinkSession($event);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_fails_when_the_javascript_session_is_used_but_not_defined($event, $mink, $feature, $suite)
|
||||||
|
{
|
||||||
|
$suite->hasSetting('mink_javascript_session')->willReturn(false);
|
||||||
$this->beConstructedWith($mink, 'goutte', null);
|
$this->beConstructedWith($mink, 'goutte', null);
|
||||||
$feature->getTags()->willReturn(array('javascript'));
|
$feature->getTags()->willReturn(array('javascript'));
|
||||||
|
|
||||||
@@ -73,8 +136,9 @@ class SessionsListenerSpec extends ObjectBehavior
|
|||||||
$this->prepareDefaultMinkSession($event);
|
$this->prepareDefaultMinkSession($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_prefers_the_scenario_over_the_feature($event, $mink, $scenario, $feature)
|
function it_prefers_the_scenario_over_the_feature($event, $mink, $scenario, $feature, $suite)
|
||||||
{
|
{
|
||||||
|
$suite->hasSetting('mink_javascript_session')->willReturn(false);
|
||||||
$scenario->getTags()->willReturn(array('mink:test'));
|
$scenario->getTags()->willReturn(array('mink:test'));
|
||||||
$feature->getTags()->willReturn(array('javascript'));
|
$feature->getTags()->willReturn(array('javascript'));
|
||||||
$mink->resetSessions()->shouldBeCalled();
|
$mink->resetSessions()->shouldBeCalled();
|
||||||
|
|||||||
@@ -255,6 +255,7 @@ class Extension implements ExtensionInterface
|
|||||||
|
|
||||||
$container->setParameter('mink.default_session', $defaultSession);
|
$container->setParameter('mink.default_session', $defaultSession);
|
||||||
$container->setParameter('mink.javascript_session', $javascriptSession);
|
$container->setParameter('mink.javascript_session', $javascriptSession);
|
||||||
|
$container->setParameter('mink.available_javascript_sessions', $javascriptSessions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadSessionsListener(ContainerBuilder $container)
|
private function loadSessionsListener(ContainerBuilder $container)
|
||||||
@@ -263,6 +264,7 @@ class Extension implements ExtensionInterface
|
|||||||
new Reference(self::MINK_ID),
|
new Reference(self::MINK_ID),
|
||||||
'%mink.default_session%',
|
'%mink.default_session%',
|
||||||
'%mink.javascript_session%',
|
'%mink.javascript_session%',
|
||||||
|
'%mink.available_javascript_sessions%',
|
||||||
));
|
));
|
||||||
$definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG, array('priority' => 0));
|
$definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG, array('priority' => 0));
|
||||||
$container->setDefinition('mink.listener.sessions', $definition);
|
$container->setDefinition('mink.listener.sessions', $definition);
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ use Behat\Behat\EventDispatcher\Event\ScenarioTested;
|
|||||||
use Behat\Mink\Mink;
|
use Behat\Mink\Mink;
|
||||||
use Behat\Testwork\EventDispatcher\Event\ExerciseCompleted;
|
use Behat\Testwork\EventDispatcher\Event\ExerciseCompleted;
|
||||||
use Behat\Testwork\ServiceContainer\Exception\ProcessingException;
|
use Behat\Testwork\ServiceContainer\Exception\ProcessingException;
|
||||||
|
use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
|
||||||
|
use Behat\Testwork\Suite\Suite;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,18 +32,25 @@ class SessionsListener implements EventSubscriberInterface
|
|||||||
private $defaultSession;
|
private $defaultSession;
|
||||||
private $javascriptSession;
|
private $javascriptSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string[] The available javascript sessions
|
||||||
|
*/
|
||||||
|
private $availableJavascriptSessions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes initializer.
|
* Initializes initializer.
|
||||||
*
|
*
|
||||||
* @param Mink $mink
|
* @param Mink $mink
|
||||||
* @param string $defaultSession
|
* @param string $defaultSession
|
||||||
* @param string|null $javascriptSession
|
* @param string|null $javascriptSession
|
||||||
|
* @param string[] $availableJavascriptSessions
|
||||||
*/
|
*/
|
||||||
public function __construct(Mink $mink, $defaultSession, $javascriptSession)
|
public function __construct(Mink $mink, $defaultSession, $javascriptSession, array $availableJavascriptSessions = array())
|
||||||
{
|
{
|
||||||
$this->mink = $mink;
|
$this->mink = $mink;
|
||||||
$this->defaultSession = $defaultSession;
|
$this->defaultSession = $defaultSession;
|
||||||
$this->javascriptSession = $javascriptSession;
|
$this->javascriptSession = $javascriptSession;
|
||||||
|
$this->availableJavascriptSessions = $availableJavascriptSessions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,20 +84,20 @@ class SessionsListener implements EventSubscriberInterface
|
|||||||
{
|
{
|
||||||
$scenario = $event->getScenario();
|
$scenario = $event->getScenario();
|
||||||
$feature = $event->getFeature();
|
$feature = $event->getFeature();
|
||||||
$session = $this->defaultSession;
|
$session = null;
|
||||||
|
|
||||||
foreach (array_merge($feature->getTags(), $scenario->getTags()) as $tag) {
|
foreach (array_merge($feature->getTags(), $scenario->getTags()) as $tag) {
|
||||||
if ('javascript' === $tag) {
|
if ('javascript' === $tag) {
|
||||||
if (null === $this->javascriptSession) {
|
$session = $this->getJavascriptSession($event->getSuite());
|
||||||
throw new ProcessingException('The @javascript tag cannot be used without enabling a javascript session');
|
|
||||||
}
|
|
||||||
|
|
||||||
$session = $this->javascriptSession;
|
|
||||||
} elseif (preg_match('/^mink\:(.+)/', $tag, $matches)) {
|
} elseif (preg_match('/^mink\:(.+)/', $tag, $matches)) {
|
||||||
$session = $matches[1];
|
$session = $matches[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null === $session) {
|
||||||
|
$session = $this->getDefaultSession($event->getSuite());
|
||||||
|
}
|
||||||
|
|
||||||
if ($scenario->hasTag('insulated') || $feature->hasTag('insulated')) {
|
if ($scenario->hasTag('insulated') || $feature->hasTag('insulated')) {
|
||||||
$this->mink->stopSessions();
|
$this->mink->stopSessions();
|
||||||
} else {
|
} else {
|
||||||
@@ -105,4 +114,64 @@ class SessionsListener implements EventSubscriberInterface
|
|||||||
{
|
{
|
||||||
$this->mink->stopSessions();
|
$this->mink->stopSessions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getDefaultSession(Suite $suite)
|
||||||
|
{
|
||||||
|
if (!$suite->hasSetting('mink_session')) {
|
||||||
|
return $this->defaultSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
$session = $suite->getSetting('mink_session');
|
||||||
|
|
||||||
|
if (!is_string($session)) {
|
||||||
|
throw new SuiteConfigurationException(
|
||||||
|
sprintf(
|
||||||
|
'`mink_session` setting of the "%s" suite is expected to be a string, %s given.',
|
||||||
|
$suite->getName(),
|
||||||
|
gettype($session)
|
||||||
|
),
|
||||||
|
$suite->getName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $session;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getJavascriptSession(Suite $suite)
|
||||||
|
{
|
||||||
|
if (!$suite->hasSetting('mink_javascript_session')) {
|
||||||
|
if (null === $this->javascriptSession) {
|
||||||
|
throw new ProcessingException('The @javascript tag cannot be used without enabling a javascript session');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->javascriptSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
$session = $suite->getSetting('mink_javascript_session');
|
||||||
|
|
||||||
|
if (!is_string($session)) {
|
||||||
|
throw new SuiteConfigurationException(
|
||||||
|
sprintf(
|
||||||
|
'`mink_javascript_session` setting of the "%s" suite is expected to be a string, %s given.',
|
||||||
|
$suite->getName(),
|
||||||
|
gettype($session)
|
||||||
|
),
|
||||||
|
$suite->getName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($session, $this->availableJavascriptSessions)) {
|
||||||
|
throw new SuiteConfigurationException(
|
||||||
|
sprintf(
|
||||||
|
'`mink_javascript_session` setting of the "%s" suite is not a javascript session. %s given but expected one of %s.',
|
||||||
|
$suite->getName(),
|
||||||
|
$session,
|
||||||
|
implode(', ', $this->availableJavascriptSessions)
|
||||||
|
),
|
||||||
|
$suite->getName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $session;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user