From cd6e02b40aa24da2f664f75342a6900fe5bdbe31 Mon Sep 17 00:00:00 2001
From: TavoNiievez <ganieves@outlook.com>
Date: Fri, 27 Sep 2024 13:33:55 -0500
Subject: [PATCH] Symfony assertion refinement

---
 composer.json                                 |   2 +-
 readme.md                                     |   2 +-
 src/Codeception/Module/Symfony.php            |   2 -
 .../Module/Symfony/BrowserAssertionsTrait.php | 118 +++++++++---------
 .../Symfony/DomCrawlerAssertionsTrait.php     | 114 +++++------------
 .../Module/Symfony/FormAssertionsTrait.php    |   4 +-
 .../Module/Symfony/MimeAssertionsTrait.php    |  16 ---
 .../Symfony/NotificationAssertionsTrait.php   |  91 --------------
 8 files changed, 89 insertions(+), 260 deletions(-)
 delete mode 100644 src/Codeception/Module/Symfony/NotificationAssertionsTrait.php

diff --git a/composer.json b/composer.json
index 0bdc3bd6..65238b1d 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 06d2d614..ccedd850 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.php b/src/Codeception/Module/Symfony.php
index 34694898..3f7917bb 100644
--- a/src/Codeception/Module/Symfony.php
+++ b/src/Codeception/Module/Symfony.php
@@ -19,7 +19,6 @@
 use Codeception\Module\Symfony\HttpClientAssertionsTrait;
 use Codeception\Module\Symfony\MailerAssertionsTrait;
 use Codeception\Module\Symfony\MimeAssertionsTrait;
-use Codeception\Module\Symfony\NotificationAssertionsTrait;
 use Codeception\Module\Symfony\ParameterAssertionsTrait;
 use Codeception\Module\Symfony\RouterAssertionsTrait;
 use Codeception\Module\Symfony\SecurityAssertionsTrait;
@@ -144,7 +143,6 @@ class Symfony extends Framework implements DoctrineProvider, PartedModule
     use HttpClientAssertionsTrait;
     use MailerAssertionsTrait;
     use MimeAssertionsTrait;
-    use NotificationAssertionsTrait;
     use ParameterAssertionsTrait;
     use RouterAssertionsTrait;
     use SecurityAssertionsTrait;
diff --git a/src/Codeception/Module/Symfony/BrowserAssertionsTrait.php b/src/Codeception/Module/Symfony/BrowserAssertionsTrait.php
index cc8bfb54..488e1976 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
      * <?php
@@ -214,7 +205,7 @@ public function rebootClientKernel(): void
 
     /**
      * Verifies that a page is available.
-     * By default, it checks the current page, specify the `$url` parameter to change it.
+     * By default, it checks the current page. Specify the `$url` parameter to change the page being checked.
      *
      * ```php
      * <?php
@@ -224,7 +215,7 @@ public function rebootClientKernel(): void
      * $I->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
      * <?php
@@ -246,21 +237,24 @@ public function seePageIsAvailable(?string $url = null): void
      */
     public function seePageRedirectsTo(string $page, string $redirectsTo): void
     {
-        $this->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
      * <?php
@@ -270,8 +264,8 @@ public function seePageRedirectsTo(string $page, string $redirectsTo): void
      * ]);
      * ```
      *
-     * @param string $name The `name` attribute of the `<form>` (you cannot use an array as selector here)
-     * @param string[] $fields
+     * @param string $name The `name` attribute of the `<form>`. You cannot use an array as a selector here.
+     * @param array<string, mixed> $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 0d5bca59..643e3fd1 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 `<title>` 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->getClient()->getCrawler(), $constraint, $message);
     }
 }
diff --git a/src/Codeception/Module/Symfony/FormAssertionsTrait.php b/src/Codeception/Module/Symfony/FormAssertionsTrait.php
index 0c8736f0..cdebbb64 100644
--- a/src/Codeception/Module/Symfony/FormAssertionsTrait.php
+++ b/src/Codeception/Module/Symfony/FormAssertionsTrait.php
@@ -17,7 +17,7 @@ trait FormAssertionsTrait
      */
     public function assertFormValue(string $formSelector, string $fieldName, string $value, string $message = ''): void
     {
-        $node = $this->getCrawler()->filter($formSelector);
+        $node = $this->getCLient()->getCrawler()->filter($formSelector);
         $this->assertNotEmpty($node, sprintf('Form "%s" not found.', $formSelector));
         $values = $node->form()->getValues();
         $this->assertArrayHasKey($fieldName, $values, $message ?: sprintf('Field "%s" not found in form "%s".', $fieldName, $formSelector));
@@ -29,7 +29,7 @@ public function assertFormValue(string $formSelector, string $fieldName, string
      */
     public function assertNoFormValue(string $formSelector, string $fieldName, string $message = ''): void
     {
-        $node = $this->getCrawler()->filter($formSelector);
+        $node = $this->getCLient()->getCrawler()->filter($formSelector);
         $this->assertNotEmpty($node, sprintf('Form "%s" not found.', $formSelector));
         $values = $node->form()->getValues();
         $this->assertArrayNotHasKey($fieldName, $values, $message ?: sprintf('Field "%s" has a value in form "%s".', $fieldName, $formSelector));
diff --git a/src/Codeception/Module/Symfony/MimeAssertionsTrait.php b/src/Codeception/Module/Symfony/MimeAssertionsTrait.php
index a55b13ba..ba2ee9ac 100644
--- a/src/Codeception/Module/Symfony/MimeAssertionsTrait.php
+++ b/src/Codeception/Module/Symfony/MimeAssertionsTrait.php
@@ -134,22 +134,6 @@ public function assertEmailNotHasHeader(string $headerName, ?Email $email = null
         $this->assertThat($email, new LogicalNot(new MimeConstraint\EmailHasHeader($headerName)));
     }
 
-    /**
-     * Asserts that the subject of the given email does contain the expected subject.
-     */
-    public function assertEmailSubjectContains(RawMessage $email, string $expectedValue, string $message = ''): void
-    {
-        $this->assertThat($email, new MimeConstraint\EmailSubjectContains($expectedValue), $message);
-    }
-
-    /**
-     * Asserts that the subject of the given email does not contain the expected subject.
-     */
-    public function assertEmailSubjectNotContains(RawMessage $email, string $expectedValue, string $message = ''): void
-    {
-        $this->assertThat($email, new LogicalNot(new MimeConstraint\EmailSubjectContains($expectedValue)), $message);
-    }
-
     /**
      * Verify the text body of an email contains a `$text`.
      * If the Email object is not specified, the last email sent is used instead.
diff --git a/src/Codeception/Module/Symfony/NotificationAssertionsTrait.php b/src/Codeception/Module/Symfony/NotificationAssertionsTrait.php
deleted file mode 100644
index c8b0f74c..00000000
--- a/src/Codeception/Module/Symfony/NotificationAssertionsTrait.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Codeception\Module\Symfony;
-
-use PHPUnit\Framework\Constraint\LogicalNot;
-use Symfony\Component\Notifier\Event\MessageEvent;
-use Symfony\Component\Notifier\Event\NotificationEvents;
-use Symfony\Component\Notifier\Message\MessageInterface;
-use Symfony\Component\Notifier\Test\Constraint\NotificationCount;
-use Symfony\Component\Notifier\Test\Constraint\NotificationIsQueued;
-use Symfony\Component\Notifier\Test\Constraint\NotificationSubjectContains;
-use Symfony\Component\Notifier\Test\Constraint\NotificationTransportIsEqual;
-
-trait NotificationAssertionsTrait
-{
-    /**
-     * Asserts that the given number of notifications has been created (in total or for the given transport).
-     */
-    public function assertNotificationCount(int $count, ?string $transportName = null, string $message = ''): void
-    {
-        $this->assertThat($this->getNotificationEvents(), new NotificationCount($count, $transportName), $message);
-    }
-
-    /**
-     * Asserts that the given notification is not queued.
-     */
-    public function assertNotificationIsNotQueued(MessageEvent $event, string $message = ''): void
-    {
-        $this->assertThat($event, new LogicalNot(new NotificationIsQueued()), $message);
-    }
-
-    /**
-     * Asserts that the given notification is queued.
-     */
-    public function assertNotificationIsQueued(MessageEvent $event, string $message = ''): void
-    {
-        $this->assertThat($event, new NotificationIsQueued(), $message);
-    }
-
-    /**
-     * Asserts that the given text is included in the subject of the given notification.
-     */
-    public function assertNotificationSubjectContains(MessageInterface $notification, string $text, string $message = ''): void
-    {
-        $this->assertThat($notification, new NotificationSubjectContains($text), $message);
-    }
-
-    /**
-     * Asserts that the given text is not included in the subject of the given notification.
-     */
-    public function assertNotificationSubjectNotContains(MessageInterface $notification, string $text, string $message = ''): void
-    {
-        $this->assertThat($notification, new LogicalNot(new NotificationSubjectContains($text)), $message);
-    }
-
-    /**
-     * Asserts that the name of the transport for the given notification is the same as the given text.
-     */
-    public function assertNotificationTransportIsEqual(MessageInterface $notification, ?string $transportName = null, string $message = ''): void
-    {
-        $this->assertThat($notification, new NotificationTransportIsEqual($transportName), $message);
-    }
-
-    /**
-     * Asserts that the name of the transport for the given notification is not the same as the given text.
-     */
-    public function assertNotificationTransportIsNotEqual(MessageInterface $notification, ?string $transportName = null, string $message = ''): void
-    {
-        $this->assertThat($notification, new LogicalNot(new NotificationTransportIsEqual($transportName)), $message);
-    }
-
-    /**
-     * Asserts that the given number of notifications are queued (in total or for the given transport).
-     */
-    public function assertQueuedNotificationCount(int $count, ?string $transportName = null, string $message = ''): void
-    {
-        $this->assertThat($this->getNotificationEvents(), new NotificationCount($count, $transportName, true), $message);
-    }
-
-    protected function getNotificationEvents(): NotificationEvents
-    {
-        $notificationLogger = $this->getService('notifier.notification_logger_listener');
-        if ($notificationLogger) {
-            return $notificationLogger->getEvents();
-        }
-
-        $this->fail('A client must have Notifier enabled to make notifications assertions. Did you forget to require symfony/notifier?');
-    }
-}