From bfe49a50abe71f3fd0af9910426955b57f963747 Mon Sep 17 00:00:00 2001 From: TavoNiievez Date: Fri, 27 Sep 2024 13:33:55 -0500 Subject: [PATCH] Symfony assertion refinement --- composer.json | 2 +- readme.md | 2 +- .../Module/Symfony/BrowserAssertionsTrait.php | 118 +++++++++--------- .../Symfony/DomCrawlerAssertionsTrait.php | 114 +++++------------ 4 files changed, 87 insertions(+), 149 deletions(-) diff --git a/composer.json b/composer.json index 0bdc3bd..65238b1 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ "symfony/http-kernel": "^5.4 | ^6.4 | ^7.0", "symfony/mailer": "^5.4 | ^6.4 | ^7.0", "symfony/mime": "^5.4 | ^6.4 | ^7.0", - "symfony/notifier": "5.4 | ^6.4 | ^7.0", + "symfony/notifier": "^5.4 | ^6.4 | ^7.0", "symfony/options-resolver": "^5.4 | ^6.4 | ^7.0", "symfony/property-access": "^5.4 | ^6.4 | ^7.0", "symfony/property-info": "^5.4 | ^6.4 | ^7.0", diff --git a/readme.md b/readme.md index 06d2d61..ccedd85 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ A Codeception module for Symfony framework. ## Requirements -* `Symfony` `5.4.x`, `6.4.x`, `7.0.x` or higher, as per the [Symfony supported versions](https://symfony.com/releases). +* `Symfony` `5.4.x`, `6.4.x`, `7.1.x` or higher, as per the [Symfony supported versions](https://symfony.com/releases). * `PHP 8.1` or higher. ## Installation diff --git a/src/Codeception/Module/Symfony/BrowserAssertionsTrait.php b/src/Codeception/Module/Symfony/BrowserAssertionsTrait.php index cc8bfb5..488e197 100644 --- a/src/Codeception/Module/Symfony/BrowserAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/BrowserAssertionsTrait.php @@ -5,7 +5,6 @@ namespace Codeception\Module\Symfony; use PHPUnit\Framework\Constraint\Constraint; -use PHPUnit\Framework\Constraint\LogicalAnd; use PHPUnit\Framework\Constraint\LogicalNot; use Symfony\Component\BrowserKit\Test\Constraint\BrowserCookieValueSame; use Symfony\Component\BrowserKit\Test\Constraint\BrowserHasCookie; @@ -25,18 +24,17 @@ trait BrowserAssertionsTrait { /** - * Asserts the given cookie in the test Client is set to the expected value. + * Asserts that the given cookie in the test client is set to the expected value. */ public function assertBrowserCookieValueSame(string $name, string $expectedValue, bool $raw = false, string $path = '/', ?string $domain = null, string $message = ''): void { - $this->assertThatForClient(LogicalAnd::fromConstraints( - new BrowserHasCookie($name, $path, $domain), - new BrowserCookieValueSame($name, $expectedValue, $raw, $path, $domain) - ), $message); + $this->assertThatForClient(new BrowserHasCookie($name, $path, $domain), $message); + $this->assertThatForClient(new BrowserCookieValueSame($name, $expectedValue, $raw, $path, $domain), $message); } /** - * Asserts that the test Client does have the given cookie set (meaning, the cookie was set by any response in the test). + * Asserts that the test client has the specified cookie set. + * This indicates that the cookie was set by any response during the test. */ public function assertBrowserHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void { @@ -44,7 +42,8 @@ public function assertBrowserHasCookie(string $name, string $path = '/', ?string } /** - * Asserts that the test Client does not have the given cookie set (meaning, the cookie was set by any response in the test). + * Asserts that the test client does not have the specified cookie set. + * This indicates that the cookie was not set by any response during the test. */ public function assertBrowserNotHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void { @@ -52,7 +51,7 @@ public function assertBrowserNotHasCookie(string $name, string $path = '/', ?str } /** - * Asserts the given request attribute is set to the expected value. + * Asserts that the specified request attribute matches the expected value. */ public function assertRequestAttributeValueSame(string $name, string $expectedValue, string $message = ''): void { @@ -60,18 +59,16 @@ public function assertRequestAttributeValueSame(string $name, string $expectedVa } /** - * Asserts the given cookie is present and set to the expected value. + * Asserts that the specified response cookie is present and matches the expected value. */ public function assertResponseCookieValueSame(string $name, string $expectedValue, string $path = '/', ?string $domain = null, string $message = ''): void { - $this->assertThatForResponse(LogicalAnd::fromConstraints( - new ResponseHasCookie($name, $path, $domain), - new ResponseCookieValueSame($name, $expectedValue, $path, $domain) - ), $message); + $this->assertThatForResponse(new ResponseHasCookie($name, $path, $domain), $message); + $this->assertThatForResponse(new ResponseCookieValueSame($name, $expectedValue, $path, $domain), $message); } /** - * Asserts the response format returned by the `Response::getFormat()` method is the same as the expected value. + * Asserts that the response format matches the expected format. This checks the format returned by the `Response::getFormat()` method. */ public function assertResponseFormatSame(?string $expectedFormat, string $message = ''): void { @@ -79,7 +76,7 @@ public function assertResponseFormatSame(?string $expectedFormat, string $messag } /** - * Asserts the given cookie is present in the response (optionally checking for a specific cookie path or domain). + * Asserts that the specified cookie is present in the response. Optionally, it can check for a specific cookie path or domain. */ public function assertResponseHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void { @@ -87,7 +84,8 @@ public function assertResponseHasCookie(string $name, string $path = '/', ?strin } /** - * Asserts the given header is available on the response, e.g. assertResponseHasHeader('content-type');. + * Asserts that the specified header is available in the response. + * For example, use `assertResponseHasHeader('content-type');`. */ public function assertResponseHasHeader(string $headerName, string $message = ''): void { @@ -95,8 +93,8 @@ public function assertResponseHasHeader(string $headerName, string $message = '' } /** - * Asserts the given header does not contain the expected value on the response, - * e.g. assertResponseHeaderNotSame('content-type', 'application/octet-stream');. + * Asserts that the specified header does not contain the expected value in the response. + * For example, use `assertResponseHeaderNotSame('content-type', 'application/octet-stream');`. */ public function assertResponseHeaderNotSame(string $headerName, string $expectedValue, string $message = ''): void { @@ -104,8 +102,8 @@ public function assertResponseHeaderNotSame(string $headerName, string $expected } /** - * Asserts the given header does contain the expected value on the response, - * e.g. assertResponseHeaderSame('content-type', 'application/octet-stream');. + * Asserts that the specified header contains the expected value in the response. + * For example, use `assertResponseHeaderSame('content-type', 'application/octet-stream');`. */ public function assertResponseHeaderSame(string $headerName, string $expectedValue, string $message = ''): void { @@ -113,7 +111,7 @@ public function assertResponseHeaderSame(string $headerName, string $expectedVal } /** - * Asserts that the response was successful (HTTP status is 2xx). + * Asserts that the response was successful (HTTP status code is in the 2xx range). */ public function assertResponseIsSuccessful(string $message = '', bool $verbose = true): void { @@ -121,7 +119,7 @@ public function assertResponseIsSuccessful(string $message = '', bool $verbose = } /** - * Asserts the response is unprocessable (HTTP status is 422) + * Asserts that the response is unprocessable (HTTP status code is 422). */ public function assertResponseIsUnprocessable(string $message = '', bool $verbose = true): void { @@ -129,7 +127,7 @@ public function assertResponseIsUnprocessable(string $message = '', bool $verbos } /** - * Asserts the given cookie is not present in the response (optionally checking for a specific cookie path or domain). + * Asserts that the specified cookie is not present in the response. Optionally, it can check for a specific cookie path or domain. */ public function assertResponseNotHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void { @@ -137,7 +135,8 @@ public function assertResponseNotHasCookie(string $name, string $path = '/', ?st } /** - * Asserts the given header is not available on the response, e.g. assertResponseNotHasHeader('content-type');. + * Asserts that the specified header is not available in the response. + * For example, use `assertResponseNotHasHeader('content-type');`. */ public function assertResponseNotHasHeader(string $headerName, string $message = ''): void { @@ -145,30 +144,27 @@ public function assertResponseNotHasHeader(string $headerName, string $message = } /** - * Asserts the response is a redirect response (optionally, you can check the target location and status code). - * The excepted location can be either an absolute or a relative path. + * Asserts that the response is a redirect. Optionally, you can check the target location and status code. + * The expected location can be either an absolute or a relative path. */ public function assertResponseRedirects(?string $expectedLocation = null, ?int $expectedCode = null, string $message = '', bool $verbose = true): void { - $constraint = new ResponseIsRedirected($verbose); - if ($expectedLocation) { - if (class_exists(ResponseHeaderLocationSame::class)) { - $locationConstraint = new ResponseHeaderLocationSame($this->getClient()->getRequest(), $expectedLocation); - } else { - $locationConstraint = new ResponseHeaderSame('Location', $expectedLocation); - } + $this->assertThatForResponse(new ResponseIsRedirected($verbose), $message); - $constraint = LogicalAnd::fromConstraints($constraint, $locationConstraint); + if ($expectedLocation) { + $constraint = class_exists(ResponseHeaderLocationSame::class) + ? new ResponseHeaderLocationSame($this->getClient()->getRequest(), $expectedLocation) + : new ResponseHeaderSame('Location', $expectedLocation); + $this->assertThatForResponse($constraint, $message); } + if ($expectedCode) { - $constraint = LogicalAnd::fromConstraints($constraint, new ResponseStatusCodeSame($expectedCode)); + $this->assertThatForResponse(new ResponseStatusCodeSame($expectedCode), $message); } - - $this->assertThatForResponse($constraint, $message); } /** - * Asserts a specific HTTP status code. + * Asserts that the response status code matches the expected code. */ public function assertResponseStatusCodeSame(int $expectedCode, string $message = '', bool $verbose = true): void { @@ -178,23 +174,18 @@ public function assertResponseStatusCodeSame(int $expectedCode, string $message /** * Asserts the request matches the given route and optionally route parameters. */ - public function assertRouteSame(string $expectedRoute, array $parameters = [], string $message = ''): void - { - $constraint = new RequestAttributeValueSame('_route', $expectedRoute); - $constraints = []; + public function assertRouteSame(string $expectedRoute, array $parameters = [], string $message = ''): void { + $request = $this->getClient()->getRequest(); + $this->assertThat($request, new RequestAttributeValueSame('_route', $expectedRoute)); + foreach ($parameters as $key => $value) { - $constraints[] = new RequestAttributeValueSame($key, $value); - } - if ($constraints) { - $constraint = LogicalAnd::fromConstraints($constraint, ...$constraints); + $this->assertThat($request, new RequestAttributeValueSame($key, $value), $message); } - - $this->assertThat($this->getClient()->getRequest(), $constraint, $message); } /** - * Reboot client's kernel. - * Can be used to manually reboot kernel when 'rebootable_client' => false + * Reboots the client's kernel. + * Can be used to manually reboot the kernel when 'rebootable_client' is set to false. * * ```php * seePageIsAvailable('/dashboard'); // Same as above * ``` * - * @param string|null $url + * @param string|null $url The URL of the page to check. If null, the current page is checked. */ public function seePageIsAvailable(?string $url = null): void { @@ -237,7 +228,7 @@ public function seePageIsAvailable(?string $url = null): void } /** - * Goes to a page and check that it redirects to another. + * Navigates to a page and verifies that it redirects to another page. * * ```php * getClient()->followRedirects(false); + $client = $this->getClient(); + $client->followRedirects(false); $this->amOnPage($page); - $response = $this->getClient()->getResponse(); + $this->assertTrue( - $response->isRedirection() + $client->getResponse()->isRedirection(), + 'The response is not a redirection.' ); - $this->getClient()->followRedirect(); + + $client->followRedirect(); $this->seeInCurrentUrl($redirectsTo); } /** - * Submit a form specifying the form name only once. + * Submits a form by specifying the form name only once. * * Use this function instead of [`$I->submitForm()`](#submitForm) to avoid repeating the form name in the field selectors. - * If you customized the names of the field selectors use `$I->submitForm()` for full control. + * If you have customized the names of the field selectors, use `$I->submitForm()` for full control. * * ```php * ` (you cannot use an array as selector here) - * @param string[] $fields + * @param string $name The `name` attribute of the `
`. You cannot use an array as a selector here. + * @param array $fields The form fields to submit. */ public function submitSymfonyForm(string $name, array $fields): void { diff --git a/src/Codeception/Module/Symfony/DomCrawlerAssertionsTrait.php b/src/Codeception/Module/Symfony/DomCrawlerAssertionsTrait.php index 0d5bca5..ea692f7 100644 --- a/src/Codeception/Module/Symfony/DomCrawlerAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/DomCrawlerAssertionsTrait.php @@ -4,62 +4,21 @@ namespace Codeception\Module\Symfony; -use PHPUnit\Framework\Constraint\LogicalAnd; +use PHPUnit\Framework\Constraint\Constraint; use PHPUnit\Framework\Constraint\LogicalNot; -use Symfony\Component\DomCrawler\Crawler; -use Symfony\Component\DomCrawler\Test\Constraint\CrawlerAnySelectorTextContains; -use Symfony\Component\DomCrawler\Test\Constraint\CrawlerAnySelectorTextSame; use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorAttributeValueSame; -use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorCount; use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorExists; use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorTextContains; use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorTextSame; trait DomCrawlerAssertionsTrait { - /** - * Asserts that any element matching the given selector does contain the expected text. - */ - public function assertAnySelectorTextContains(string $selector, string $text, string $message = ''): void - { - $this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints( - new CrawlerSelectorExists($selector), - new CrawlerAnySelectorTextContains($selector, $text) - ), $message); - } - - /** - * Asserts that any element matching the given selector does not contain the expected text. - */ - public function assertAnySelectorTextNotContains(string $selector, string $text, string $message = ''): void - { - $this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints( - new CrawlerSelectorExists($selector), - new LogicalNot(new CrawlerAnySelectorTextContains($selector, $text)) - ), $message); - } - - /** - * Asserts that any element matching the given selector does equal the expected text. - */ - public function assertAnySelectorTextSame(string $selector, string $text, string $message = ''): void - { - $this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints( - new CrawlerSelectorExists($selector), - new CrawlerAnySelectorTextSame($selector, $text) - ), $message); - } - /** * Asserts that the checkbox with the given name is checked. */ public function assertCheckboxChecked(string $fieldName, string $message = ''): void { - $this->assertThat( - $this->getCrawler(), - new CrawlerSelectorExists("input[name=\"$fieldName\"]:checked"), - $message - ); + $this->assertThatCrawler(new CrawlerSelectorExists("input[name=\"$fieldName\"]:checked"), $message); } /** @@ -67,33 +26,32 @@ public function assertCheckboxChecked(string $fieldName, string $message = ''): */ public function assertCheckboxNotChecked(string $fieldName, string $message = ''): void { - $this->assertThat( - $this->getCrawler(), - new LogicalNot(new CrawlerSelectorExists("input[name=\"$fieldName\"]:checked")), - $message - ); + $this->assertThatCrawler(new LogicalNot( + new CrawlerSelectorExists("input[name=\"$fieldName\"]:checked") + ), $message); } /** - * Asserts that value of the form input with the given name does not equal the expected value. + * Asserts that the value of the form input with the given name does not equal the expected value. */ public function assertInputValueNotSame(string $fieldName, string $expectedValue, string $message = ''): void { - $this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints( - new CrawlerSelectorExists("input[name=\"$fieldName\"]"), - new LogicalNot(new CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue)) + $this->assertThatCrawler(new CrawlerSelectorExists("input[name=\"$fieldName\"]"), $message); + $this->assertThatCrawler(new LogicalNot( + new CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue) ), $message); } /** - * Asserts that value of the form input with the given name does equal the expected value. + * Asserts that the value of the form input with the given name equals the expected value. */ public function assertInputValueSame(string $fieldName, string $expectedValue, string $message = ''): void { - $this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints( - new CrawlerSelectorExists("input[name=\"$fieldName\"]"), - new CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue) - ), $message); + $this->assertThatCrawler(new CrawlerSelectorExists("input[name=\"$fieldName\"]"), $message); + $this->assertThatCrawler( + new CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue), + $message + ); } /** @@ -105,7 +63,7 @@ public function assertPageTitleContains(string $expectedTitle, string $message = } /** - * Asserts that the `` element is equal to the given title. + * Asserts that the `<title>` element equals the given title. */ public function assertPageTitleSame(string $expectedTitle, string $message = ''): void { @@ -113,19 +71,11 @@ public function assertPageTitleSame(string $expectedTitle, string $message = '') } /** - * Asserts that the expected number of selector elements are in the response. - */ - public function assertSelectorCount(int $expectedCount, string $selector, string $message = ''): void - { - $this->assertThat($this->getCrawler(), new CrawlerSelectorCount($expectedCount, $selector), $message); - } - - /** - * Asserts that the given selector does match at least one element in the response. + * Asserts that the given selector matches at least one element in the response. */ public function assertSelectorExists(string $selector, string $message = ''): void { - $this->assertThat($this->getCrawler(), new CrawlerSelectorExists($selector), $message); + $this->assertThatCrawler(new CrawlerSelectorExists($selector), $message); } /** @@ -133,18 +83,16 @@ public function assertSelectorExists(string $selector, string $message = ''): vo */ public function assertSelectorNotExists(string $selector, string $message = ''): void { - $this->assertThat($this->getCrawler(), new LogicalNot(new CrawlerSelectorExists($selector)), $message); + $this->assertThatCrawler(new LogicalNot(new CrawlerSelectorExists($selector)), $message); } /** - * Asserts that the first element matching the given selector does contain the expected text. + * Asserts that the first element matching the given selector contains the expected text. */ public function assertSelectorTextContains(string $selector, string $text, string $message = ''): void { - $this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints( - new CrawlerSelectorExists($selector), - new CrawlerSelectorTextContains($selector, $text) - ), $message); + $this->assertThatCrawler(new CrawlerSelectorExists($selector), $message); + $this->assertThatCrawler(new CrawlerSelectorTextContains($selector, $text), $message); } /** @@ -152,25 +100,21 @@ public function assertSelectorTextContains(string $selector, string $text, strin */ public function assertSelectorTextNotContains(string $selector, string $text, string $message = ''): void { - $this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints( - new CrawlerSelectorExists($selector), - new LogicalNot(new CrawlerSelectorTextContains($selector, $text)) - ), $message); + $this->assertThatCrawler(new CrawlerSelectorExists($selector), $message); + $this->assertThatCrawler(new LogicalNot(new CrawlerSelectorTextContains($selector, $text)), $message); } /** - * Asserts that the contents of the first element matching the given selector does equal the expected text. + * Asserts that the text of the first element matching the given selector equals the expected text. */ public function assertSelectorTextSame(string $selector, string $text, string $message = ''): void { - $this->assertThat($this->getCrawler(), LogicalAnd::fromConstraints( - new CrawlerSelectorExists($selector), - new CrawlerSelectorTextSame($selector, $text) - ), $message); + $this->assertThatCrawler(new CrawlerSelectorExists($selector), $message); + $this->assertThatCrawler(new CrawlerSelectorTextSame($selector, $text), $message); } - protected function getCrawler(): Crawler + protected function assertThatCrawler(Constraint $constraint, string $message): void { - return $this->client->getCrawler(); + $this->assertThat($this->client->getCrawler(), $constraint, $message); } }