Skip to content

Commit

Permalink
Merge pull request #3 from Zales0123/symfony-support
Browse files Browse the repository at this point in the history
Symfony support
  • Loading branch information
lchrusciel authored Jul 4, 2018
2 parents 9dfdda8 + 4523feb commit 23bf73a
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ inspired by [sensiolabs/BehatPageObjectExtension](https://github.com/sensiolabs/

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

### SymfonyPage

`SymfonyPage` is an extension of `Page` class for better and more straightforward Symfony application support.
This concept is also extracted from [Sylius Behat system](https://github.com/Sylius/Sylius/tree/master/src/Sylius/Behat/Page)

## Installation

```bash
Expand Down
9 changes: 9 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@

"behat/mink": "^1.7"
},
"require-dev": {
"symfony/routing": "^3.4"
},
"suggest": {
"symfony/routing": "Allow better support for PageObject pattern in Symfony applications"
},
"conflict": {
"symfony/routing": "<3.4"
},
"autoload": {
"psr-4": { "FriendsOfBehat\\PageObjectExtension\\": "src/" }
}
Expand Down
115 changes: 115 additions & 0 deletions src/Page/SymfonyPage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

declare(strict_types=1);

namespace FriendsOfBehat\PageObjectExtension\Page;

use Behat\Mink\Session;
use Symfony\Component\Routing\RouterInterface;

abstract class SymfonyPage extends Page implements SymfonyPageInterface
{
/** @var RouterInterface */
protected $router;

/** @var array */
protected static $additionalParameters = ['_locale' => 'en_US'];

public function __construct(Session $session, array $parameters, RouterInterface $router)
{
parent::__construct($session, $parameters);

$this->router = $router;
}

abstract public function getRouteName(): string;

/**
* @throws UnexpectedPageException
*/
public function verifyRoute(array $requiredUrlParameters = []): void
{
$url = $this->getDriver()->getCurrentUrl();
$path = parse_url($url)['path'];

$path = preg_replace('#^/app(_dev|_test|_test_cached)?\.php/#', '/', $path);
$matchedRoute = $this->router->match($path);

$this->verifyRouteName($matchedRoute, $url);
$this->verifyRouteParameters($requiredUrlParameters, $matchedRoute);
}

final protected function makePathAbsolute(string $path): string
{
$baseUrl = rtrim($this->getParameter('base_url'), '/') . '/';

return 0 !== strpos($path, 'http') ? $baseUrl . ltrim($path, '/') : $path;
}

protected function getUrl(array $urlParameters = []): string
{
$path = $this->router->generate($this->getRouteName(), $urlParameters + static::$additionalParameters);

$replace = [];
foreach (static::$additionalParameters as $key => $value) {
$replace[sprintf('&%s=%s', $key, $value)] = '';
$replace[sprintf('?%s=%s&', $key, $value)] = '?';
$replace[sprintf('?%s=%s', $key, $value)] = '';
}

$path = str_replace(array_keys($replace), array_values($replace), $path);

return $this->makePathAbsolute($path);
}

protected function verifyUrl(array $urlParameters = []): void
{
$url = $this->getDriver()->getCurrentUrl();
$path = parse_url($url)['path'];

$path = preg_replace('#^/app(_dev|_test|_test_cached)?\.php/#', '/', $path);
$matchedRoute = $this->router->match($path);

if (isset($matchedRoute['_locale'])) {
$urlParameters += ['_locale' => $matchedRoute['_locale']];
}

parent::verifyUrl($urlParameters);
}

/**
* @throws UnexpectedPageException
*/
private function verifyRouteName(array $matchedRoute, string $url): void
{
if ($matchedRoute['_route'] !== $this->getRouteName()) {
throw new UnexpectedPageException(
sprintf(
"Matched route '%s' does not match the expected route '%s' for URL '%s'",
$matchedRoute['_route'],
$this->getRouteName(),
$url
)
);
}
}

/**
* @throws UnexpectedPageException
*/
private function verifyRouteParameters(array $requiredUrlParameters, array $matchedRoute): void
{
foreach ($requiredUrlParameters as $key => $value) {
if (!isset($matchedRoute[$key]) || $matchedRoute[$key] !== $value) {
throw new UnexpectedPageException(
sprintf(
"Matched route does not match the expected parameter '%s'='%s' (%s found)",
$key,
$value,
$matchedRoute[$key] ?? 'null'
)
);
}
}
}
}
15 changes: 15 additions & 0 deletions src/Page/SymfonyPageInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace FriendsOfBehat\PageObjectExtension\Page;

interface SymfonyPageInterface extends PageInterface
{
public function getRouteName(): string;

/**
* @throws UnexpectedPageException
*/
public function verifyRoute(array $requiredUrlParameters = []): void;
}

0 comments on commit 23bf73a

Please sign in to comment.