Completed
Push — master ( 230277...eb7ff0 )
by Michał
93:10 queued 79:08
created

Page::tryToOpen()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Behat\PageObjectExtension\PageObject;
13
14
use Behat\Mink\Driver\DriverInterface;
15
use Behat\Mink\Element\DocumentElement;
16
use Behat\Mink\Exception\DriverException;
17
use Behat\Mink\Session;
18
use SensioLabs\Behat\PageObjectExtension\PageObject\Element;
19
use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\ElementNotFoundException;
20
use SensioLabs\Behat\PageObjectExtension\PageObject\Exception\UnexpectedPageException;
21
use SensioLabs\Behat\PageObjectExtension\PageObject\Factory;
22
use SensioLabs\Behat\PageObjectExtension\PageObject\PageObject;
23
24
/**
25
 * @author Kamil Kokot <[email protected]>
26
 */
27
abstract class Page implements PageObject
28
{
29
    /**
30
     * @var array
31
     */
32
    protected $elements = [];
33
34
    /**
35
     * @var Session
36
     */
37
    private $session;
38
39
    /**
40
     * @var Factory
41
     */
42
    private $factory;
43
44
    /**
45
     * @var array
46
     */
47
    private $parameters;
48
49
    /**
50
     * @var DocumentElement
51
     */
52
    private $document;
53
54
    /**
55
     * @param Session $session
56
     * @param Factory $factory
57
     * @param array $parameters
58
     */
59
    public function __construct(Session $session, Factory $factory, array $parameters = [])
60
    {
61
        $this->session = $session;
62
        $this->factory = $factory;
63
        $this->parameters = $parameters;
64
65
        $this->document = new DocumentElement($session);
66
    }
67
68
    /**
69
     * @param array $urlParameters
70
     *
71
     * @throws UnexpectedPageException If page is not opened successfully
72
     */
73
    public function open(array $urlParameters = [])
74
    {
75
        $this->tryToOpen($urlParameters);
76
        $this->verify($urlParameters);
77
    }
78
79
    /**
80
     * @param array $urlParameters
81
     */
82
    public function tryToOpen(array $urlParameters = [])
83
    {
84
        $this->getDriver()->visit($this->getUrl($urlParameters));
85
    }
86
87
    /**
88
     * @param array $urlParameters
89
     *
90
     * @throws UnexpectedPageException
91
     */
92
    public function verify(array $urlParameters)
93
    {
94
        $this->verifyResponse();
95
        $this->verifyUrl($urlParameters);
96
        $this->verifyPage();
97
    }
98
99
    /**
100
     * @param array $urlParameters
101
     *
102
     * @return bool
103
     */
104
    public function isOpen(array $urlParameters = [])
105
    {
106
        try {
107
            $this->verify($urlParameters);
108
        } catch (\Exception $e) {
109
            return false;
110
        }
111
112
        return true;
113
    }
114
115
    /**
116
     * @return string
117
     */
118
    abstract protected function getPath();
119
120
    /**
121
     * @return string
122
     */
123
    protected function getName()
124
    {
125
        return preg_replace('/^.*\\\(.*?)$/', '$1', get_called_class());
126
    }
127
128
    /**
129
     * @param array $urlParameters
130
     *
131
     * @return string
132
     */
133
    protected function getUrl(array $urlParameters = [])
134
    {
135
        return $this->makeSurePathIsAbsolute($this->unmaskUrl($urlParameters));
136
    }
137
138
    /**
139
     * @throws UnexpectedPageException
140
     */
141
    protected function verifyResponse()
142
    {
143
        try {
144
            $statusCode = $this->getDriver()->getStatusCode();
145
146
            if ($this->isErrorResponse($statusCode)) {
147
                $currentUrl = $this->getDriver()->getCurrentUrl();
148
                $message = sprintf('Could not open the page: "%s". Received an error status code: %s', $currentUrl, $statusCode);
149
150
                throw new UnexpectedPageException($message);
151
            }
152
        } catch (DriverException $exception) {
153
            // ignore drivers which cannot check the response status code
154
        }
155
    }
156
157
    /**
158
     * Overload to verify if the current url matches the expected one. Throw an exception otherwise.
159
     *
160
     * @param array $urlParameters
161
     */
162
    protected function verifyUrl(array $urlParameters = [])
163
    {
164
        if ($this->getDriver()->getCurrentUrl() !== $this->getUrl($urlParameters)) {
165
            throw new UnexpectedPageException(sprintf('Expected to be on "%s" but found "%s" instead', $this->getUrl($urlParameters), $this->getDriver()->getCurrentUrl()));
166
        }
167
    }
168
169
    /**
170
     * Overload to verify if we're on an expected page. Throw an exception otherwise.
171
     *
172
     * @throws UnexpectedPageException
173
     */
174
    protected function verifyPage()
175
    {
176
    }
177
178
    /**
179
     * @param int $statusCode
180
     *
181
     * @return bool
182
     */
183
    protected function isErrorResponse($statusCode)
184
    {
185
        return 400 <= $statusCode && $statusCode < 600;
186
    }
187
188
    /**
189
     * @param string $name
190
     *
191
     * @return string|null
192
     */
193
    protected function getParameter($name)
194
    {
195
        return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
196
    }
197
198
    /**
199
     * @param string $name
200
     *
201
     * @return Element
202
     */
203
    public function getElement($name)
204
    {
205
        $element = $this->createElement($name);
206
207
        if (!$this->getDocument()->has('xpath', $element->getXpath())) {
208
            throw new ElementNotFoundException(sprintf('"%s" element is not present on the page', $name));
209
        }
210
211
        return $element;
212
    }
213
214
    /**
215
     * @param string $name
216
     *
217
     * @return bool
218
     */
219
    protected function hasElement($name)
220
    {
221
        return $this->getDocument()->has('xpath', $this->createElement($name)->getXpath());
222
    }
223
224
    /**
225
     * @param string $name
226
     *
227
     * @return Element
228
     */
229
    protected function createElement($name)
230
    {
231
        if (isset($this->elements[$name])) {
232
            return $this->factory->createInlineElement($this->elements[$name]);
233
        }
234
235
        return $this->factory->createElement($name);
236
    }
237
238
    /**
239
     * @return Session
240
     */
241
    protected function getSession()
242
    {
243
        return $this->session;
244
    }
245
246
    /**
247
     * @return DriverInterface
248
     */
249
    protected function getDriver()
250
    {
251
        return $this->session->getDriver();
252
    }
253
254
    /**
255
     * @return DocumentElement
256
     */
257
    protected function getDocument()
258
    {
259
        return $this->document;
260
    }
261
262
    /**
263
     * @param string $path
264
     *
265
     * @return string
266
     */
267
    private function makeSurePathIsAbsolute($path)
268
    {
269
        $baseUrl = rtrim($this->getParameter('base_url'), '/').'/';
270
271
        return 0 !== strpos($path, 'http') ? $baseUrl.ltrim($path, '/') : $path;
272
    }
273
274
    /**
275
     * @param array $urlParameters
276
     *
277
     * @return string
278
     */
279
    private function unmaskUrl(array $urlParameters)
280
    {
281
        $url = $this->getPath();
282
283
        foreach ($urlParameters as $parameter => $value) {
284
            $url = str_replace(sprintf('{%s}', $parameter), $value, $url);
285
        }
286
287
        return $url;
288
    }
289
}
290