Skip to content

Commit 1987a3d

Browse files
committed
get the inherent Symfony assertions
1 parent 9b77251 commit 1987a3d

File tree

5 files changed

+424
-57
lines changed

5 files changed

+424
-57
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"type": "library",
66
"keywords": [
77
"codeception",
8+
"functional testing",
89
"symfony"
910
],
1011
"authors": [

src/Codeception/Module/Symfony.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Codeception\Module\Symfony\BrowserAssertionsTrait;
1414
use Codeception\Module\Symfony\ConsoleAssertionsTrait;
1515
use Codeception\Module\Symfony\DoctrineAssertionsTrait;
16+
use Codeception\Module\Symfony\DomCrawlerAssertionsTrait;
1617
use Codeception\Module\Symfony\EventsAssertionsTrait;
1718
use Codeception\Module\Symfony\FormAssertionsTrait;
1819
use Codeception\Module\Symfony\MailerAssertionsTrait;
@@ -135,6 +136,7 @@ class Symfony extends Framework implements DoctrineProvider, PartedModule
135136
use BrowserAssertionsTrait;
136137
use ConsoleAssertionsTrait;
137138
use DoctrineAssertionsTrait;
139+
use DomCrawlerAssertionsTrait;
138140
use EventsAssertionsTrait;
139141
use FormAssertionsTrait;
140142
use MailerAssertionsTrait;

src/Codeception/Module/Symfony/BrowserAssertionsTrait.php

Lines changed: 194 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,191 @@
44

55
namespace Codeception\Module\Symfony;
66

7+
use PHPUnit\Framework\Constraint\Constraint;
8+
use PHPUnit\Framework\Constraint\LogicalAnd;
9+
use PHPUnit\Framework\Constraint\LogicalNot;
10+
use Symfony\Component\BrowserKit\Test\Constraint\BrowserCookieValueSame;
11+
use Symfony\Component\BrowserKit\Test\Constraint\BrowserHasCookie;
12+
use Symfony\Component\HttpFoundation\Test\Constraint\RequestAttributeValueSame;
13+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseCookieValueSame;
14+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseFormatSame;
15+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHasCookie;
16+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHasHeader;
17+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHeaderLocationSame;
18+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHeaderSame;
19+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseIsRedirected;
720
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseIsSuccessful;
21+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseIsUnprocessable;
22+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseStatusCodeSame;
823
use function sprintf;
924

1025
trait BrowserAssertionsTrait
1126
{
27+
/**
28+
* Asserts the response format returned by the `Response::getFormat()` method is the same as the expected value.
29+
*/
30+
public function assertResponseFormatSame(?string $expectedFormat, string $message = ''): void
31+
{
32+
$this->assertThatForResponse(new ResponseFormatSame($this->getClient()->getRequest(), $expectedFormat), $message);
33+
}
34+
35+
/**
36+
* Asserts a specific HTTP status code.
37+
*/
38+
public function assertResponseStatusCodeSame(int $expectedCode, string $message = '', bool $verbose = true): void
39+
{
40+
$this->assertThatForResponse(new ResponseStatusCodeSame($expectedCode, $verbose), $message);
41+
}
42+
43+
/**
44+
* Asserts the response is a redirect response (optionally, you can check the target location and status code).
45+
* The excepted location can be either an absolute or a relative path.
46+
*/
47+
public function assertResponseRedirects(?string $expectedLocation = null, ?int $expectedCode = null, string $message = '', bool $verbose = true): void
48+
{
49+
$constraint = new ResponseIsRedirected($verbose);
50+
if ($expectedLocation) {
51+
if (class_exists(ResponseHeaderLocationSame::class)) {
52+
$locationConstraint = new ResponseHeaderLocationSame($this->getClient()->getRequest(), $expectedLocation);
53+
} else {
54+
$locationConstraint = new ResponseHeaderSame('Location', $expectedLocation);
55+
}
56+
57+
$constraint = LogicalAnd::fromConstraints($constraint, $locationConstraint);
58+
}
59+
if ($expectedCode) {
60+
$constraint = LogicalAnd::fromConstraints($constraint, new ResponseStatusCodeSame($expectedCode));
61+
}
62+
63+
$this->assertThatForResponse($constraint, $message);
64+
}
65+
66+
/**
67+
* Asserts the given header is available on the response, e.g. assertResponseHasHeader('content-type');.
68+
*/
69+
public function assertResponseHasHeader(string $headerName, string $message = ''): void
70+
{
71+
$this->assertThatForResponse(new ResponseHasHeader($headerName), $message);
72+
}
73+
74+
/**
75+
* Asserts the given header is not available on the response, e.g. assertResponseNotHasHeader('content-type');.
76+
*/
77+
public function assertResponseNotHasHeader(string $headerName, string $message = ''): void
78+
{
79+
$this->assertThatForResponse(new LogicalNot(new ResponseHasHeader($headerName)), $message);
80+
}
81+
82+
/**
83+
* Asserts the given header does contain the expected value on the response,
84+
* e.g. assertResponseHeaderSame('content-type', 'application/octet-stream');.
85+
*/
86+
public function assertResponseHeaderSame(string $headerName, string $expectedValue, string $message = ''): void
87+
{
88+
$this->assertThatForResponse(new ResponseHeaderSame($headerName, $expectedValue), $message);
89+
}
90+
91+
/**
92+
* Asserts the given header does not contain the expected value on the response,
93+
* e.g. assertResponseHeaderNotSame('content-type', 'application/octet-stream');.
94+
*/
95+
public function assertResponseHeaderNotSame(string $headerName, string $expectedValue, string $message = ''): void
96+
{
97+
$this->assertThatForResponse(new LogicalNot(new ResponseHeaderSame($headerName, $expectedValue)), $message);
98+
}
99+
100+
/**
101+
* Asserts the given cookie is present in the response (optionally checking for a specific cookie path or domain).
102+
*/
103+
public function assertResponseHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
104+
{
105+
$this->assertThatForResponse(new ResponseHasCookie($name, $path, $domain), $message);
106+
}
107+
108+
/**
109+
* Asserts the given cookie is not present in the response (optionally checking for a specific cookie path or domain).
110+
*/
111+
public function assertResponseNotHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
112+
{
113+
$this->assertThatForResponse(new LogicalNot(new ResponseHasCookie($name, $path, $domain)), $message);
114+
}
115+
116+
/**
117+
* Asserts the given cookie is present and set to the expected value.
118+
*/
119+
public function assertResponseCookieValueSame(string $name, string $expectedValue, string $path = '/', ?string $domain = null, string $message = ''): void
120+
{
121+
$this->assertThatForResponse(LogicalAnd::fromConstraints(
122+
new ResponseHasCookie($name, $path, $domain),
123+
new ResponseCookieValueSame($name, $expectedValue, $path, $domain)
124+
), $message);
125+
}
126+
127+
/**
128+
* Asserts the response is unprocessable (HTTP status is 422)
129+
*/
130+
public function assertResponseIsUnprocessable(string $message = '', bool $verbose = true): void
131+
{
132+
$this->assertThatForResponse(new ResponseIsUnprocessable($verbose), $message);
133+
}
134+
135+
/**
136+
* Asserts that the test Client does have the given cookie set (meaning, the cookie was set by any response in the test).
137+
*/
138+
public function assertBrowserHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
139+
{
140+
$this->assertThatForClient(new BrowserHasCookie($name, $path, $domain), $message);
141+
}
142+
143+
protected function assertThatForClient(Constraint $constraint, string $message = ''): void
144+
{
145+
$this->assertThat($this->getClient(), $constraint, $message);
146+
}
147+
148+
/**
149+
* Asserts that the test Client does not have the given cookie set (meaning, the cookie was set by any response in the test).
150+
*/
151+
public function assertBrowserNotHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
152+
{
153+
$this->assertThatForClient(new LogicalNot(new BrowserHasCookie($name, $path, $domain)), $message);
154+
}
155+
156+
/**
157+
* Asserts the given cookie in the test Client is set to the expected value.
158+
*/
159+
public function assertBrowserCookieValueSame(string $name, string $expectedValue, bool $raw = false, string $path = '/', ?string $domain = null, string $message = ''): void
160+
{
161+
$this->assertThatForClient(LogicalAnd::fromConstraints(
162+
new BrowserHasCookie($name, $path, $domain),
163+
new BrowserCookieValueSame($name, $expectedValue, $raw, $path, $domain)
164+
), $message);
165+
}
166+
167+
/**
168+
* Asserts the given request attribute is set to the expected value.
169+
*/
170+
public function assertRequestAttributeValueSame(string $name, string $expectedValue, string $message = ''): void
171+
{
172+
$this->assertThat($this->getClient()->getRequest(), new RequestAttributeValueSame($name, $expectedValue), $message);
173+
}
174+
175+
/**
176+
* Asserts the request matches the given route and optionally route parameters.
177+
*/
178+
public function assertRouteSame(string $expectedRoute, array $parameters = [], string $message = ''): void
179+
{
180+
$constraint = new RequestAttributeValueSame('_route', $expectedRoute);
181+
$constraints = [];
182+
foreach ($parameters as $key => $value) {
183+
$constraints[] = new RequestAttributeValueSame($key, $value);
184+
}
185+
if ($constraints) {
186+
$constraint = LogicalAnd::fromConstraints($constraint, ...$constraints);
187+
}
188+
189+
$this->assertThat($this->getClient()->getRequest(), $constraint, $message);
190+
}
191+
12192
/**
13193
* Reboot client's kernel.
14194
* Can be used to manually reboot kernel when 'rebootable_client' => false
@@ -50,7 +230,15 @@ public function seePageIsAvailable(?string $url = null): void
50230
$this->seeInCurrentUrl($url);
51231
}
52232

53-
$this->assertThat($this->getClient()->getResponse(), new ResponseIsSuccessful());
233+
$this->assertResponseIsSuccessful();
234+
}
235+
236+
/**
237+
* Asserts that the response was successful (HTTP status is 2xx).
238+
*/
239+
public function assertResponseIsSuccessful(string $message = '', bool $verbose = true): void
240+
{
241+
$this->assertThatForResponse(new ResponseIsSuccessful($verbose), $message);
54242
}
55243

56244
/**
@@ -104,4 +292,9 @@ public function submitSymfonyForm(string $name, array $fields): void
104292

105293
$this->submitForm($selector, $params, $button);
106294
}
295+
296+
protected function assertThatForResponse(Constraint $constraint, string $message = ''): void
297+
{
298+
$this->assertThat($this->getClient()->getResponse(), $constraint, $message);
299+
}
107300
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Codeception\Module\Symfony;
6+
7+
use PHPUnit\Framework\Constraint\LogicalAnd;
8+
use PHPUnit\Framework\Constraint\LogicalNot;
9+
use Symfony\Component\DomCrawler\Crawler;
10+
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerAnySelectorTextContains;
11+
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerAnySelectorTextSame;
12+
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorAttributeValueSame;
13+
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorCount;
14+
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorExists;
15+
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorTextContains;
16+
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorTextSame;
17+
18+
trait DomCrawlerAssertionsTrait
19+
{
20+
public function assertSelectorExists(string $selector, string $message = ''): void
21+
{
22+
$this->assertThat($this->getCrawler(), new CrawlerSelectorExists($selector), $message);
23+
}
24+
25+
public function assertSelectorNotExists(string $selector, string $message = ''): void
26+
{
27+
$this->assertThat($this->getCrawler(), new LogicalNot(new CrawlerSelectorExists($selector)), $message);
28+
}
29+
30+
public function assertSelectorCount(int $expectedCount, string $selector, string $message = ''): void
31+
{
32+
$this->assertThat($this->getCrawler(), new CrawlerSelectorCount($expectedCount, $selector), $message);
33+
}
34+
35+
public function assertAnySelectorTextContains(string $selector, string $text, string $message = ''): void
36+
{
37+
$this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints(
38+
new CrawlerSelectorExists($selector),
39+
new CrawlerAnySelectorTextContains($selector, $text)
40+
), $message);
41+
}
42+
43+
public function assertAnySelectorTextSame(string $selector, string $text, string $message = ''): void
44+
{
45+
$this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints(
46+
new CrawlerSelectorExists($selector),
47+
new CrawlerAnySelectorTextSame($selector, $text)
48+
), $message);
49+
}
50+
51+
public function assertSelectorTextNotContains(string $selector, string $text, string $message = ''): void
52+
{
53+
$this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints(
54+
new CrawlerSelectorExists($selector),
55+
new LogicalNot(new CrawlerSelectorTextContains($selector, $text))
56+
), $message);
57+
}
58+
59+
public function assertAnySelectorTextNotContains(string $selector, string $text, string $message = ''): void
60+
{
61+
$this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints(
62+
new CrawlerSelectorExists($selector),
63+
new LogicalNot(new CrawlerAnySelectorTextContains($selector, $text))
64+
), $message);
65+
}
66+
67+
public function assertPageTitleSame(string $expectedTitle, string $message = ''): void
68+
{
69+
$this->assertSelectorTextSame('title', $expectedTitle, $message);
70+
}
71+
72+
public function assertSelectorTextSame(string $selector, string $text, string $message = ''): void
73+
{
74+
$this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints(
75+
new CrawlerSelectorExists($selector),
76+
new CrawlerSelectorTextSame($selector, $text)
77+
), $message);
78+
}
79+
80+
public function assertPageTitleContains(string $expectedTitle, string $message = ''): void
81+
{
82+
$this->assertSelectorTextContains('title', $expectedTitle, $message);
83+
}
84+
85+
public function assertSelectorTextContains(string $selector, string $text, string $message = ''): void
86+
{
87+
$this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints(
88+
new CrawlerSelectorExists($selector),
89+
new CrawlerSelectorTextContains($selector, $text)
90+
), $message);
91+
}
92+
93+
public function assertInputValueSame(string $fieldName, string $expectedValue, string $message = ''): void
94+
{
95+
$this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints(
96+
new CrawlerSelectorExists("input[name=\"$fieldName\"]"),
97+
new CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue)
98+
), $message);
99+
}
100+
101+
public function assertInputValueNotSame(string $fieldName, string $expectedValue, string $message = ''): void
102+
{
103+
$this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints(
104+
new CrawlerSelectorExists("input[name=\"$fieldName\"]"),
105+
new LogicalNot(new CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue))
106+
), $message);
107+
}
108+
109+
/**
110+
* Asserts that the checkbox with the given name is checked.
111+
*/
112+
public function assertCheckboxChecked(string $fieldName, string $message = ''): void
113+
{
114+
$this->assertThat(
115+
$this->getCrawler(),
116+
new CrawlerSelectorExists("input[name=\"$fieldName\"]:checked"),
117+
$message
118+
);
119+
}
120+
121+
/**
122+
* Asserts that the checkbox with the given name is not checked.
123+
*/
124+
public function assertCheckboxNotChecked(string $fieldName, string $message = ''): void
125+
{
126+
$this->assertThat(
127+
$this->getCrawler(),
128+
new LogicalNot(new CrawlerSelectorExists("input[name=\"$fieldName\"]:checked")),
129+
$message
130+
);
131+
}
132+
133+
protected function getCrawler(): Crawler
134+
{
135+
return $this->client->getCrawler();
136+
}
137+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy