1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the Behat MinkExtension. |
5
|
|
|
* (c) Konstantin Kudryashov <[email protected]> |
6
|
|
|
* |
7
|
|
|
* For the full copyright and license information, please view the LICENSE |
8
|
|
|
* file that was distributed with this source code. |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace Behat\MinkExtension\Listener; |
12
|
|
|
|
13
|
|
|
use Behat\Behat\EventDispatcher\Event\ExampleTested; |
14
|
|
|
use Behat\Behat\EventDispatcher\Event\ScenarioLikeTested; |
15
|
|
|
use Behat\Behat\EventDispatcher\Event\ScenarioTested; |
16
|
|
|
use Behat\Mink\Mink; |
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; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Mink sessions listener. |
25
|
|
|
* Listens Behat events and configures/stops Mink sessions. |
26
|
|
|
* |
27
|
|
|
* @author Konstantin Kudryashov <[email protected]> |
28
|
|
|
*/ |
29
|
|
|
class SessionsListener implements EventSubscriberInterface |
30
|
|
|
{ |
31
|
|
|
private $mink; |
32
|
|
|
private $defaultSession; |
33
|
|
|
private $javascriptSession; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var string[] The available javascript sessions |
37
|
|
|
*/ |
38
|
|
|
private $availableJavascriptSessions; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Initializes initializer. |
42
|
|
|
* |
43
|
|
|
* @param Mink $mink |
44
|
|
|
* @param string $defaultSession |
45
|
|
|
* @param string|null $javascriptSession |
46
|
|
|
* @param string[] $availableJavascriptSessions |
47
|
|
|
*/ |
48
|
|
|
public function __construct(Mink $mink, $defaultSession, $javascriptSession, array $availableJavascriptSessions = array()) |
49
|
|
|
{ |
50
|
|
|
$this->mink = $mink; |
51
|
|
|
$this->defaultSession = $defaultSession; |
52
|
|
|
$this->javascriptSession = $javascriptSession; |
53
|
|
|
$this->availableJavascriptSessions = $availableJavascriptSessions; |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* {@inheritdoc} |
58
|
|
|
*/ |
59
|
|
|
public static function getSubscribedEvents() |
60
|
|
|
{ |
61
|
|
|
return array( |
62
|
|
|
ScenarioTested::BEFORE => array('prepareDefaultMinkSession', 10), |
63
|
|
|
ExampleTested::BEFORE => array('prepareDefaultMinkSession', 10), |
64
|
|
|
ExerciseCompleted::AFTER => array('tearDownMinkSessions', -10) |
65
|
|
|
); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Configures default Mink session before each scenario. |
70
|
|
|
* Configuration is based on provided scenario tags: |
71
|
|
|
* |
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 |
75
|
|
|
* |
76
|
|
|
* `@insulated` tag will cause Mink to stop current sessions before scenario |
77
|
|
|
* instead of just soft-resetting them |
78
|
|
|
* |
79
|
|
|
* @param ScenarioLikeTested $event |
80
|
|
|
* |
81
|
|
|
* @throws ProcessingException when the @javascript tag is used without a javascript session |
82
|
|
|
*/ |
83
|
|
|
public function prepareDefaultMinkSession(ScenarioLikeTested $event) |
84
|
|
|
{ |
85
|
|
|
$scenario = $event->getScenario(); |
86
|
|
|
$feature = $event->getFeature(); |
87
|
|
|
$session = null; |
88
|
|
|
|
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]; |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
if (null === $session) { |
98
|
|
|
$session = $this->getDefaultSession($event->getSuite()); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
if ($scenario->hasTag('insulated') || $feature->hasTag('insulated')) { |
102
|
|
|
$this->mink->stopSessions(); |
103
|
|
|
} else { |
104
|
|
|
$this->mink->resetSessions(); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
$this->mink->setDefaultSessionName($session); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Stops all started Mink sessions. |
112
|
|
|
*/ |
113
|
|
|
public function tearDownMinkSessions() |
114
|
|
|
{ |
115
|
|
|
$this->mink->stopSessions(); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
private function getDefaultSession(Suite $suite) |
119
|
|
|
{ |
120
|
|
|
if (!$suite->hasSetting('mink_session')) { |
121
|
|
|
return $this->defaultSession; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
$session = $suite->getSetting('mink_session'); |
125
|
|
|
|
126
|
|
View Code Duplication |
if (!is_string($session)) { |
|
|
|
|
127
|
|
|
throw new SuiteConfigurationException( |
128
|
|
|
sprintf( |
129
|
|
|
'`mink_session` setting of the "%s" suite is expected to be a string, %s given.', |
130
|
|
|
$suite->getName(), |
131
|
|
|
gettype($session) |
132
|
|
|
), |
133
|
|
|
$suite->getName() |
134
|
|
|
); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
return $session; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
private function getJavascriptSession(Suite $suite) |
141
|
|
|
{ |
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'); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
return $this->javascriptSession; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
$session = $suite->getSetting('mink_javascript_session'); |
151
|
|
|
|
152
|
|
View Code Duplication |
if (!is_string($session)) { |
|
|
|
|
153
|
|
|
throw new SuiteConfigurationException( |
154
|
|
|
sprintf( |
155
|
|
|
'`mink_javascript_session` setting of the "%s" suite is expected to be a string, %s given.', |
156
|
|
|
$suite->getName(), |
157
|
|
|
gettype($session) |
158
|
|
|
), |
159
|
|
|
$suite->getName() |
160
|
|
|
); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
if (!in_array($session, $this->availableJavascriptSessions)) { |
164
|
|
|
throw new SuiteConfigurationException( |
165
|
|
|
sprintf( |
166
|
|
|
'`mink_javascript_session` setting of the "%s" suite is not a javascript session. %s given but expected one of %s.', |
167
|
|
|
$suite->getName(), |
168
|
|
|
$session, |
169
|
|
|
implode(', ', $this->availableJavascriptSessions) |
170
|
|
|
), |
171
|
|
|
$suite->getName() |
172
|
|
|
); |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
return $session; |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.