4 * This file is part of the Behat MinkExtension.
5 * (c) Konstantin Kudryashov <ever.zet@gmail.com>
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
11 namespace Behat\MinkExtension\Listener;
13 use Behat\Behat\EventDispatcher\Event\ExampleTested;
14 use Behat\Behat\EventDispatcher\Event\ScenarioLikeTested;
15 use Behat\Behat\EventDispatcher\Event\ScenarioTested;
17 use Behat\Testwork\EventDispatcher\Event\ExerciseCompleted;
18 use Behat\Testwork\ServiceContainer\Exception\ProcessingException;
19 use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
20 use Behat\Testwork\Suite\Suite;
21 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
24 * Mink sessions listener.
25 * Listens Behat events and configures/stops Mink sessions.
27 * @author Konstantin Kudryashov <ever.zet@gmail.com>
29 class SessionsListener implements EventSubscriberInterface
32 private $defaultSession;
33 private $javascriptSession;
36 * @var string[] The available javascript sessions
38 private $availableJavascriptSessions;
41 * Initializes initializer.
44 * @param string $defaultSession
45 * @param string|null $javascriptSession
46 * @param string[] $availableJavascriptSessions
48 public function __construct(Mink $mink, $defaultSession, $javascriptSession, array $availableJavascriptSessions = array())
51 $this->defaultSession = $defaultSession;
52 $this->javascriptSession = $javascriptSession;
53 $this->availableJavascriptSessions = $availableJavascriptSessions;
59 public static function getSubscribedEvents()
62 ScenarioTested::BEFORE => array('prepareDefaultMinkSession', 10),
63 ExampleTested::BEFORE => array('prepareDefaultMinkSession', 10),
64 ExerciseCompleted::AFTER => array('tearDownMinkSessions', -10)
69 * Configures default Mink session before each scenario.
70 * Configuration is based on provided scenario tags:
72 * `@javascript` tagged scenarios will get `javascript_session` as default session
73 * `@mink:CUSTOM_NAME tagged scenarios will get `CUSTOM_NAME` as default session
74 * Other scenarios get `default_session` as default session
76 * `@insulated` tag will cause Mink to stop current sessions before scenario
77 * instead of just soft-resetting them
79 * @param ScenarioLikeTested $event
81 * @throws ProcessingException when the @javascript tag is used without a javascript session
83 public function prepareDefaultMinkSession(ScenarioLikeTested $event)
85 $scenario = $event->getScenario();
86 $feature = $event->getFeature();
89 foreach (array_merge($feature->getTags(), $scenario->getTags()) as $tag) {
90 if ('javascript' === $tag) {
91 $session = $this->getJavascriptSession($event->getSuite());
92 } elseif (preg_match('/^mink\:(.+)/', $tag, $matches)) {
93 $session = $matches[1];
97 if (null === $session) {
98 $session = $this->getDefaultSession($event->getSuite());
101 if ($scenario->hasTag('insulated') || $feature->hasTag('insulated')) {
102 $this->mink->stopSessions();
104 $this->mink->resetSessions();
107 $this->mink->setDefaultSessionName($session);
111 * Stops all started Mink sessions.
113 public function tearDownMinkSessions()
115 $this->mink->stopSessions();
118 private function getDefaultSession(Suite $suite)
120 if (!$suite->hasSetting('mink_session')) {
121 return $this->defaultSession;
124 $session = $suite->getSetting('mink_session');
126 if (!is_string($session)) {
127 throw new SuiteConfigurationException(
129 '`mink_session` setting of the "%s" suite is expected to be a string, %s given.',
140 private function getJavascriptSession(Suite $suite)
142 if (!$suite->hasSetting('mink_javascript_session')) {
143 if (null === $this->javascriptSession) {
144 throw new ProcessingException('The @javascript tag cannot be used without enabling a javascript session');
147 return $this->javascriptSession;
150 $session = $suite->getSetting('mink_javascript_session');
152 if (!is_string($session)) {
153 throw new SuiteConfigurationException(
155 '`mink_javascript_session` setting of the "%s" suite is expected to be a string, %s given.',
163 if (!in_array($session, $this->availableJavascriptSessions)) {
164 throw new SuiteConfigurationException(
166 '`mink_javascript_session` setting of the "%s" suite is not a javascript session. %s given but expected one of %s.',
169 implode(', ', $this->availableJavascriptSessions)