Skip to content

Commit 23bf73a

Browse files
authored
Merge pull request #3 from Zales0123/symfony-support
Symfony support
2 parents 9dfdda8 + 4523feb commit 23bf73a

File tree

4 files changed

+144
-0
lines changed

4 files changed

+144
-0
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ inspired by [sensiolabs/BehatPageObjectExtension](https://github.com/sensiolabs/
1212

1313
`Element` represents part of the page. This concept is extracted from [SyliusAdminOrderCreation](https://github.com/Sylius/AdminOrderCreationPlugin/blob/master/tests/Behat/Element/Element.php).
1414

15+
### SymfonyPage
16+
17+
`SymfonyPage` is an extension of `Page` class for better and more straightforward Symfony application support.
18+
This concept is also extracted from [Sylius Behat system](https://github.com/Sylius/Sylius/tree/master/src/Sylius/Behat/Page)
19+
1520
## Installation
1621

1722
```bash

composer.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424

2525
"behat/mink": "^1.7"
2626
},
27+
"require-dev": {
28+
"symfony/routing": "^3.4"
29+
},
30+
"suggest": {
31+
"symfony/routing": "Allow better support for PageObject pattern in Symfony applications"
32+
},
33+
"conflict": {
34+
"symfony/routing": "<3.4"
35+
},
2736
"autoload": {
2837
"psr-4": { "FriendsOfBehat\\PageObjectExtension\\": "src/" }
2938
}

src/Page/SymfonyPage.php

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FriendsOfBehat\PageObjectExtension\Page;
6+
7+
use Behat\Mink\Session;
8+
use Symfony\Component\Routing\RouterInterface;
9+
10+
abstract class SymfonyPage extends Page implements SymfonyPageInterface
11+
{
12+
/** @var RouterInterface */
13+
protected $router;
14+
15+
/** @var array */
16+
protected static $additionalParameters = ['_locale' => 'en_US'];
17+
18+
public function __construct(Session $session, array $parameters, RouterInterface $router)
19+
{
20+
parent::__construct($session, $parameters);
21+
22+
$this->router = $router;
23+
}
24+
25+
abstract public function getRouteName(): string;
26+
27+
/**
28+
* @throws UnexpectedPageException
29+
*/
30+
public function verifyRoute(array $requiredUrlParameters = []): void
31+
{
32+
$url = $this->getDriver()->getCurrentUrl();
33+
$path = parse_url($url)['path'];
34+
35+
$path = preg_replace('#^/app(_dev|_test|_test_cached)?\.php/#', '/', $path);
36+
$matchedRoute = $this->router->match($path);
37+
38+
$this->verifyRouteName($matchedRoute, $url);
39+
$this->verifyRouteParameters($requiredUrlParameters, $matchedRoute);
40+
}
41+
42+
final protected function makePathAbsolute(string $path): string
43+
{
44+
$baseUrl = rtrim($this->getParameter('base_url'), '/') . '/';
45+
46+
return 0 !== strpos($path, 'http') ? $baseUrl . ltrim($path, '/') : $path;
47+
}
48+
49+
protected function getUrl(array $urlParameters = []): string
50+
{
51+
$path = $this->router->generate($this->getRouteName(), $urlParameters + static::$additionalParameters);
52+
53+
$replace = [];
54+
foreach (static::$additionalParameters as $key => $value) {
55+
$replace[sprintf('&%s=%s', $key, $value)] = '';
56+
$replace[sprintf('?%s=%s&', $key, $value)] = '?';
57+
$replace[sprintf('?%s=%s', $key, $value)] = '';
58+
}
59+
60+
$path = str_replace(array_keys($replace), array_values($replace), $path);
61+
62+
return $this->makePathAbsolute($path);
63+
}
64+
65+
protected function verifyUrl(array $urlParameters = []): void
66+
{
67+
$url = $this->getDriver()->getCurrentUrl();
68+
$path = parse_url($url)['path'];
69+
70+
$path = preg_replace('#^/app(_dev|_test|_test_cached)?\.php/#', '/', $path);
71+
$matchedRoute = $this->router->match($path);
72+
73+
if (isset($matchedRoute['_locale'])) {
74+
$urlParameters += ['_locale' => $matchedRoute['_locale']];
75+
}
76+
77+
parent::verifyUrl($urlParameters);
78+
}
79+
80+
/**
81+
* @throws UnexpectedPageException
82+
*/
83+
private function verifyRouteName(array $matchedRoute, string $url): void
84+
{
85+
if ($matchedRoute['_route'] !== $this->getRouteName()) {
86+
throw new UnexpectedPageException(
87+
sprintf(
88+
"Matched route '%s' does not match the expected route '%s' for URL '%s'",
89+
$matchedRoute['_route'],
90+
$this->getRouteName(),
91+
$url
92+
)
93+
);
94+
}
95+
}
96+
97+
/**
98+
* @throws UnexpectedPageException
99+
*/
100+
private function verifyRouteParameters(array $requiredUrlParameters, array $matchedRoute): void
101+
{
102+
foreach ($requiredUrlParameters as $key => $value) {
103+
if (!isset($matchedRoute[$key]) || $matchedRoute[$key] !== $value) {
104+
throw new UnexpectedPageException(
105+
sprintf(
106+
"Matched route does not match the expected parameter '%s'='%s' (%s found)",
107+
$key,
108+
$value,
109+
$matchedRoute[$key] ?? 'null'
110+
)
111+
);
112+
}
113+
}
114+
}
115+
}

src/Page/SymfonyPageInterface.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FriendsOfBehat\PageObjectExtension\Page;
6+
7+
interface SymfonyPageInterface extends PageInterface
8+
{
9+
public function getRouteName(): string;
10+
11+
/**
12+
* @throws UnexpectedPageException
13+
*/
14+
public function verifyRoute(array $requiredUrlParameters = []): void;
15+
}

0 commit comments

Comments
 (0)