Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"symfony/css-selector": "^4.4|^5.0",
"symfony/framework-bundle": "^4.4|^5.0",
"symfony/polyfill-php80": "^1.20",
"zenstruck/assert": "^1.0",
"zenstruck/callback": "^1.1"
},
"require-dev": {
Expand Down
30 changes: 10 additions & 20 deletions src/Browser.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
use Behat\Mink\Mink;
use Behat\Mink\Session;
use Behat\Mink\WebAssert;
use PHPUnit\Framework\Assert as PHPUnit;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\Filesystem\Filesystem;
use Zenstruck\Browser\Assertion\MinkAssertion;
use Zenstruck\Browser\Assertion\SameUrlAssertion;
use Zenstruck\Browser\Component;
use Zenstruck\Browser\Response;
use Zenstruck\Browser\Test\Constraint\UrlMatches;
use Zenstruck\Callback\Parameter;

/**
Expand Down Expand Up @@ -57,13 +57,13 @@ final public function visit(string $uri): self
}

/**
* @param array $parts The url parts to check (@see parse_url)
* @param array $parts The url parts to check {@see parse_url} (use empty array for "all")
*
* @return static
*/
final public function assertOn(string $expected, array $parts = ['path', 'query', 'fragment']): self
{
PHPUnit::assertThat($expected, new UrlMatches($this->minkSession()->getCurrentUrl(), $parts));
Assert::run(new SameUrlAssertion($this->minkSession()->getCurrentUrl(), $expected, $parts));

return $this;
}
Expand All @@ -75,10 +75,7 @@ final public function assertOn(string $expected, array $parts = ['path', 'query'
*/
final public function assertNotOn(string $expected, array $parts = ['path', 'query', 'fragment']): self
{
PHPUnit::assertThat(
$expected,
PHPUnit::logicalNot(new UrlMatches($this->minkSession()->getCurrentUrl(), $parts))
);
Assert::not(new SameUrlAssertion($this->minkSession()->getCurrentUrl(), $expected, $parts));

return $this;
}
Expand Down Expand Up @@ -374,12 +371,11 @@ final public function assertSelected(string $selector, string $expected): self
{
try {
$field = $this->webAssert()->fieldExists($selector);
PHPUnit::assertTrue(true);
} catch (ExpectationException $e) {
PHPUnit::fail($e->getMessage());
Assert::fail($e->getMessage());
}

PHPUnit::assertContains($expected, (array) $field->getValue());
Assert::that((array) $field->getValue())->contains($expected);

return $this;
}
Expand All @@ -391,12 +387,11 @@ final public function assertNotSelected(string $selector, string $expected): sel
{
try {
$field = $this->webAssert()->fieldExists($selector);
PHPUnit::assertTrue(true);
} catch (ExpectationException $e) {
PHPUnit::fail($e->getMessage());
Assert::fail($e->getMessage());
}

PHPUnit::assertNotContains($expected, (array) $field->getValue());
Assert::that((array) $field->getValue())->doesNotContain($expected);

return $this;
}
Expand Down Expand Up @@ -493,12 +488,7 @@ final protected function documentElement(): DocumentElement
*/
final protected function wrapMinkExpectation(callable $callback): self
{
try {
$callback();
PHPUnit::assertTrue(true);
} catch (ExpectationException $e) {
PHPUnit::fail($e->getMessage());
}
Assert::run(new MinkAssertion($callback));

return $this;
}
Expand Down
31 changes: 31 additions & 0 deletions src/Browser/Assertion/MinkAssertion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Zenstruck\Browser\Assertion;

use Behat\Mink\Exception\ExpectationException;
use Zenstruck\Assert\AssertionFailed;

/**
* @author Kevin Bond <kevinbond@gmail.com>
*
* @internal
*/
final class MinkAssertion
{
/** @var callable */
private $callback;

public function __construct(callable $callback)
{
$this->callback = $callback;
}

public function __invoke(): void
{
try {
($this->callback)();
} catch (ExpectationException $e) {
AssertionFailed::throw($e->getMessage());
}
}
}
77 changes: 77 additions & 0 deletions src/Browser/Assertion/SameUrlAssertion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace Zenstruck\Browser\Assertion;

use Zenstruck\Assert\Assertion\Negatable;
use Zenstruck\Assert\AssertionFailed;

/**
* @author Kevin Bond <kevinbond@gmail.com>
*
* @internal
*/
final class SameUrlAssertion implements Negatable
{
private string $current;
private string $expected;
private array $partsToMatch;

public function __construct(string $current, string $expected, array $partsToMatch = [])
{
$this->current = $current;
$this->expected = $expected;
$this->partsToMatch = $partsToMatch;
}

public function __invoke(): void
{
$parsedCurrent = $this->parseUrl($this->current);
$parsedExpected = $this->parseUrl($this->expected);

if ($parsedCurrent === $parsedExpected) {
return;
}

AssertionFailed::throw(
'Expected current URL ({current}) to be "{expected}" (comparing parts: "{parts}").',
\array_merge($this->context(), [
'compare_actual' => $parsedCurrent,
'compare_expected' => $parsedExpected,
])
);
}

public function notFailure(): AssertionFailed
{
return new AssertionFailed(
'Expected current URL ({current}) to not be "{expected}" (comparing parts: "{parts}").',
$this->context()
);
}

private function context(): array
{
return [
'current' => $this->current,
'expected' => $this->expected,
'parts' => \implode(', ', $this->partsToMatch),
];
}

private function parseUrl(string $url): array
{
$parts = \parse_url(\urldecode($url));

if (empty($this->partsToMatch)) {
return $parts;
}

foreach (\array_keys($parts) as $part) {
if (!\in_array($part, $this->partsToMatch, true)) {
unset($parts[$part]);
}
}

return $parts;
}
}
12 changes: 8 additions & 4 deletions src/Browser/BrowserKitBrowser.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Zenstruck\Browser;

use PHPUnit\Framework\Assert as PHPUnit;
use Symfony\Component\BrowserKit\AbstractBrowser;
use Symfony\Component\HttpKernel\Profiler\Profile;
use Zenstruck\Assert;
use Zenstruck\Browser;
use Zenstruck\Browser\Mink\BrowserKitDriver;

Expand Down Expand Up @@ -171,7 +171,9 @@ final public function assertStatus(int $expected): self
*/
final public function assertSuccessful(): self
{
PHPUnit::assertTrue($this->response()->isSuccessful(), "Expected successful status code (2xx), [{$this->response()->statusCode()}] received.");
Assert::true($this->response()->isSuccessful(), 'Expected successful status code (2xx) but got {actual}.', [
'actual' => $this->response()->statusCode(),
]);

return $this;
}
Expand All @@ -185,7 +187,9 @@ final public function assertRedirected(): self
throw new \RuntimeException('Cannot assert redirected if not intercepting redirects. Call ->interceptRedirects() before making the request.');
}

PHPUnit::assertTrue($this->response()->isRedirect(), "Expected redirect status code (3xx), [{$this->response()->statusCode()}] received.");
Assert::true($this->response()->isRedirect(), 'Expected redirect status code (3xx) but got {actual}.', [
'actual' => $this->response()->statusCode(),
]);

return $this;
}
Expand Down Expand Up @@ -226,7 +230,7 @@ final public function assertJson(string $expectedContentType = 'json'): self
*/
final public function assertJsonMatches(string $expression, $expected): self
{
PHPUnit::assertSame($expected, $this->response()->assertJson()->search($expression));
Assert::that($this->response()->assertJson()->search($expression))->is($expected);

return $this;
}
Expand Down
12 changes: 6 additions & 6 deletions src/Browser/PantherBrowser.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Zenstruck\Browser;

use PHPUnit\Framework\Assert as PHPUnit;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Panther\Client;
use Symfony\Component\VarDumper\VarDumper;
use Zenstruck\Assert;
use Zenstruck\Browser;
use Zenstruck\Browser\Mink\PantherDriver;
use Zenstruck\Browser\Response\PantherResponse;
Expand Down Expand Up @@ -53,11 +53,11 @@ final public function setConsoleLogDir(string $dir): self
final public function follow(string $link): self
{
if (!$element = $this->documentElement()->findLink($link)) {
PHPUnit::fail(\sprintf('Link "%s" not found.', $link));
Assert::fail('Link "%s" not found.', [$link]);
}

if (!$element->isVisible()) {
PHPUnit::fail(\sprintf('Link "%s" is not visible.', $link));
Assert::fail('Link "%s" is not visible.', [$link]);
}

$this->documentElement()->clickLink($link);
Expand All @@ -73,7 +73,7 @@ final public function assertVisible(string $selector): self
return $this->wrapMinkExpectation(function() use ($selector) {
$element = $this->webAssert()->elementExists('css', $selector);

PHPUnit::assertTrue($element->isVisible());
Assert::true($element->isVisible(), 'Expected element "%s" to be visible but it isn\'t.', [$selector]);
});
}

Expand All @@ -85,12 +85,12 @@ final public function assertNotVisible(string $selector): self
$element = $this->documentElement()->find('css', $selector);

if (!$element) {
PHPUnit::assertTrue(true);
Assert::pass();

return $this;
}

PHPUnit::assertFalse($element->isVisible());
Assert::false($element->isVisible(), 'Expected element "%s" to not be visible but it is.', [$selector]);

return $this;
}
Expand Down
10 changes: 5 additions & 5 deletions src/Browser/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
namespace Zenstruck\Browser;

use Behat\Mink\Session;
use PHPUnit\Framework\Assert as PHPUnit;
use Symfony\Component\VarDumper\VarDumper;
use Zenstruck\Assert;
use Zenstruck\Browser\Response\DomResponse;
use Zenstruck\Browser\Response\HtmlResponse;
use Zenstruck\Browser\Response\JsonResponse;
Expand Down Expand Up @@ -60,7 +60,7 @@ final public function body(): string
final public function assertJson(): JsonResponse
{
if (!$this instanceof JsonResponse) {
PHPUnit::fail('Not a json response.');
Assert::fail('Not a json response.');
}

return $this;
Expand All @@ -69,7 +69,7 @@ final public function assertJson(): JsonResponse
final public function assertXml(): XmlResponse
{
if (!$this instanceof XmlResponse) {
PHPUnit::fail('Not an xml response.');
Assert::fail('Not an xml response.');
}

return $this;
Expand All @@ -78,7 +78,7 @@ final public function assertXml(): XmlResponse
final public function assertHtml(): HtmlResponse
{
if (!$this instanceof HtmlResponse) {
PHPUnit::fail('Not an html response.');
Assert::fail('Not an html response.');
}

return $this;
Expand All @@ -87,7 +87,7 @@ final public function assertHtml(): HtmlResponse
final public function assertDom(): DomResponse
{
if (!$this instanceof DomResponse) {
PHPUnit::fail('Not an DOM response.');
Assert::fail('Not an DOM response.');
}

return $this;
Expand Down
54 changes: 0 additions & 54 deletions src/Browser/Test/Constraint/UrlMatches.php

This file was deleted.