Failed Conditions
Pull Request — master (#100)
by Michał
02:11
created

SharedSessionStrategy::_switchToMainWindow()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * This file is part of the phpunit-mink library.
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 *
7
 * @copyright Alexander Obuhovich <[email protected]>
8
 * @link      https://github.com/aik099/phpunit-mink
9
 */
10
11
namespace aik099\PHPUnit\Session;
12
13
14
use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration;
15
use aik099\PHPUnit\BrowserTestCase;
16
use aik099\PHPUnit\Event\TestEvent;
17
use aik099\PHPUnit\Event\TestFailedEvent;
18
use Behat\Mink\Session;
19
use PHPUnit\Framework\IncompleteTestError;
20
use PHPUnit\Framework\SkippedTestError;
21
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
22
23
/**
24
 * Keeps a Session object shared between test runs to save time.
25
 *
26
 * @method \Mockery\Expectation shouldReceive(string $name)
27
 */
28
class SharedSessionStrategy implements ISessionStrategy
29
{
30
31
	/**
32
	 * Original session strategy.
33
	 *
34
	 * @var ISessionStrategy
35
	 */
36
	private $_originalStrategy;
37
38
	/**
39
	 * Reference to created session.
40
	 *
41
	 * @var Session
42
	 */
43
	private $_session;
44
45
	/**
46
	 * Remembers if last test failed.
47
	 *
48
	 * @var boolean
49
	 */
50
	private $_lastTestFailed = false;
51
52
	/**
53
	 * Remembers original session strategy upon shared strategy creation.
54
	 *
55
	 * @param ISessionStrategy $original_strategy Original session strategy.
56
	 */
57 7
	public function __construct(ISessionStrategy $original_strategy)
58
	{
59 7
		$this->_originalStrategy = $original_strategy;
60 7
	}
61
62
	/**
63
	 * Returns an array of event names this subscriber wants to listen to.
64
	 *
65
	 * @return array The event names to listen to
66
	 */
67 7
	public static function getSubscribedEvents()
68
	{
69
		return array(
70 7
			BrowserTestCase::TEST_FAILED_EVENT => array('onTestFailed', 0),
71 7
			BrowserTestCase::TEST_SUITE_ENDED_EVENT => array('onTestSuiteEnd', 0),
72
		);
73
	}
74
75
	/**
76
	 * Sets event dispatcher.
77
	 *
78
	 * @param EventDispatcherInterface $event_dispatcher Event dispatcher.
79
	 *
80
	 * @return void
81
	 */
82 7
	public function setEventDispatcher(EventDispatcherInterface $event_dispatcher)
83
	{
84 7
		$event_dispatcher->addSubscriber($this);
85 7
	}
86
87
	/**
88
	 * Returns Mink session with given browser configuration.
89
	 *
90
	 * @param BrowserConfiguration $browser Browser configuration for a session.
91
	 *
92
	 * @return Session
93
	 */
94 5
	public function session(BrowserConfiguration $browser)
95
	{
96 5
		if ( $this->_lastTestFailed ) {
97 2
			$this->stopSession();
98 2
			$this->_lastTestFailed = false;
99
		}
100
101 5
		if ( $this->_session === null ) {
102 5
			$this->_session = $this->_originalStrategy->session($browser);
103
		}
104
		else {
105 4
			$this->_switchToMainWindow();
106
		}
107
108 5
		return $this->_session;
109
	}
110
111
	/**
112
	 * Stops session.
113
	 *
114
	 * @return void
115
	 */
116 2
	protected function stopSession()
117
	{
118 2
		if ( $this->_session === null ) {
119 1
			return;
120
		}
121
122 1
		$this->_session->stop();
123 1
		$this->_session = null;
124 1
	}
125
126
	/**
127
	 * Switches to window, that was created upon session creation.
128
	 *
129
	 * @return void
130
	 */
131 4
	private function _switchToMainWindow()
132
	{
133 4
		$this->_session->switchToWindow(null);
134 4
	}
135
136
	/**
137
	 * Called, when test fails.
138
	 *
139
	 * @param TestFailedEvent $event Test failed event.
140
	 *
141
	 * @return void
142
	 */
143 4
	public function onTestFailed(TestFailedEvent $event)
144
	{
145 4
		if ( $event->getException() instanceof IncompleteTestError ) {
146 1
			return;
147
		}
148 3
		elseif ( $event->getException() instanceof SkippedTestError ) {
149 1
			return;
150
		}
151
152 2
		$this->_lastTestFailed = true;
153 2
	}
154
155
	/**
156
	 * Called, when test case ends.
157
	 *
158
	 * @param TestEvent $event Test event.
159
	 *
160
	 * @return void
161
	 */
162 1
	public function onTestSuiteEnd(TestEvent $event)
163
	{
164 1
		if ( !$this->_isEventForMe($event) ) {
165
			return;
166
		}
167
168 1
		$session = $event->getSession();
169
170 1
		if ( $session !== null && $session->isStarted() ) {
171 1
			$session->stop();
172
		}
173 1
	}
174
175
	/**
176
	 * Checks, that event can be handled by this class.
177
	 *
178
	 * @param TestEvent $event Test event.
179
	 *
180
	 * @return boolean
181
	 */
182 1
	private function _isEventForMe(TestEvent $event)
183
	{
184 1
		return $event->getTestCase()->getSessionStrategy() instanceof self;
185
	}
186
187
}
188