diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationActionsTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationActionsTest.php
index 148e09a1f9..9d67a6ff68 100644
--- a/core/modules/content_moderation/tests/src/Functional/ModerationActionsTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/ModerationActionsTest.php
@@ -3,7 +3,6 @@
namespace Drupal\Tests\content_moderation\Functional;
use Drupal\node\Entity\Node;
-use Drupal\Tests\AssertStatusMessageTrait;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
@@ -17,7 +16,6 @@ class ModerationActionsTest extends BrowserTestBase {
use ContentTypeCreationTrait;
use ContentModerationTestTrait;
- use AssertStatusMessageTrait;
/**
* Modules to enable.
@@ -83,14 +81,14 @@ public function testNodeStatusActions($action, $bundle, $warning_appears, $start
if ($warning_appears) {
if ($action == 'node_publish_action') {
- $this->assertStatusMessageExists(node_get_type_label($node) . ' content items were skipped as they are under moderation and may not be directly published.');
+ $this->assertSession()->statusMessageExists(node_get_type_label($node) . ' content items were skipped as they are under moderation and may not be directly published.', 'warning');
}
else {
- $this->assertStatusMessageExists(node_get_type_label($node) . ' content items were skipped as they are under moderation and may not be directly unpublished.', 'warning');
+ $this->assertSession()->statusMessageExists(node_get_type_label($node) . ' content items were skipped as they are under moderation and may not be directly unpublished.', 'warning');
}
}
else {
- $this->assertStatusMessageNotExists(NULL, 'warning');
+ $this->assertSession()->statusMessageNotExists(NULL, 'warning');
}
// Ensure after the action has run, the node matches the expected status.
diff --git a/core/modules/file/tests/src/FunctionalJavascript/MaximumFileSizeExceededUploadTest.php b/core/modules/file/tests/src/FunctionalJavascript/MaximumFileSizeExceededUploadTest.php
index d2a79aa574..5fef582215 100644
--- a/core/modules/file/tests/src/FunctionalJavascript/MaximumFileSizeExceededUploadTest.php
+++ b/core/modules/file/tests/src/FunctionalJavascript/MaximumFileSizeExceededUploadTest.php
@@ -4,7 +4,6 @@
use Drupal\Component\Utility\Bytes;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
-use Drupal\Tests\AssertJavascriptStatusMessageTrait;
use Drupal\Tests\TestFileCreationTrait;
use Drupal\Tests\file\Functional\FileFieldCreationTrait;
@@ -17,7 +16,6 @@ class MaximumFileSizeExceededUploadTest extends WebDriverTestBase {
use FileFieldCreationTrait;
use TestFileCreationTrait;
- use AssertJavascriptStatusMessageTrait;
/**
* {@inheritdoc}
@@ -113,13 +111,13 @@ public function testUploadFileExceedingMaximumFileSize() {
// the maximum file size. The error message includes the actual file size
// limit which depends on the current environment, so we check for a part
// of the message.
- $this->assertStatusMessageVisibleAfterWait('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size', 'error');
+ $this->assertSession()->statusMessageVisibleAfterWait('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size', 'error');
// Now upload a valid file and check that the error message disappears.
$valid_file = $this->generateFile('not_exceeding_post_max_size', 8, 8);
$page->attachFileToField("files[field_file_0]", $this->fileSystem->realpath($valid_file));
$this->assertSession()->waitForElement('named', ['id_or_name', 'field_file_0_remove_button']);
- $this->assertNoStatusMessageAfterWait(NULL, 'error');
+ $this->assertSession()->statusMessageNotVisibleAfterWait(NULL, 'error');
}
}
diff --git a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php
index 53399192c0..ecfe7fe174 100644
--- a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php
+++ b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php
@@ -147,12 +147,12 @@ public function messengerServiceTest() {
}
/**
- * Sets messages for testing the AssertStatusMessageTrait.
+ * Sets messages for testing the WebAssert methods related to messages.
*
* @return string
* Empty string, we just test the setting of messages.
*/
- public function assertStatusMessageTraitTest() {
+ public function statusMessagesForAssertions() {
// Add a simple message of each type.
$this->messenger->addMessage('My Status Message', 'status');
$this->messenger->addMessage('My Error Message', 'error');
diff --git a/core/modules/system/tests/modules/system_test/system_test.routing.yml b/core/modules/system/tests/modules/system_test/system_test.routing.yml
index 80cfbebeab..59b5d9116e 100644
--- a/core/modules/system/tests/modules/system_test/system_test.routing.yml
+++ b/core/modules/system/tests/modules/system_test/system_test.routing.yml
@@ -21,11 +21,11 @@ system_test.messenger_service:
requirements:
_access: 'TRUE'
-system_test.assert_status_message_trait_test:
- path: '/system-test/assert-status-message-trait-test'
+system_test.status_messages_for_assertions:
+ path: '/system-test/status-messages-for-assertions'
defaults:
- _title: 'Set messages with Messenger service'
- _controller: '\Drupal\system_test\Controller\SystemTestController::assertStatusMessageTraitTest'
+ _title: 'Set various message to test status message assertion methods'
+ _controller: '\Drupal\system_test\Controller\SystemTestController::statusMessagesForAssertions'
requirements:
_access: 'TRUE'
diff --git a/core/modules/system/tests/src/Functional/Bootstrap/DrupalMessengerServiceTest.php b/core/modules/system/tests/src/Functional/Bootstrap/DrupalMessengerServiceTest.php
index d24af2c9de..2e1c4202f4 100644
--- a/core/modules/system/tests/src/Functional/Bootstrap/DrupalMessengerServiceTest.php
+++ b/core/modules/system/tests/src/Functional/Bootstrap/DrupalMessengerServiceTest.php
@@ -3,7 +3,6 @@
namespace Drupal\Tests\system\Functional\Bootstrap;
use Drupal\Core\Url;
-use Drupal\Tests\AssertStatusMessageTrait;
use Drupal\Tests\BrowserTestBase;
/**
@@ -13,8 +12,6 @@
*/
class DrupalMessengerServiceTest extends BrowserTestBase {
- use AssertStatusMessageTrait;
-
/**
* Modules to enable.
*
@@ -65,45 +62,45 @@ public function testDrupalMessengerService() {
}
/**
- * Tests the AssertStatusMessageTrait.
+ * Tests assertion methods in WebAssert related to status messages.
*/
- public function testAssertStatusMessageTrait() {
- $this->drupalGet(Url::fromRoute('system_test.assert_status_message_trait_test'));
+ public function testStatusMessageAssertions() {
+ $this->drupalGet(Url::fromRoute('system_test.status_messages_for_assertions'));
// Use the simple messages to test basic functionality.
// Test with no args.
- $this->assertStatusMessageExists();
+ $this->assertSession()->statusMessageExists();
// Test with no second arg.
- $this->assertStatusMessageExists('My Status Message');
- $this->assertStatusMessageExists('My Error Message');
- $this->assertStatusMessageExists('My Warning Message');
+ $this->assertSession()->statusMessageExists('My Status Message');
+ $this->assertSession()->statusMessageExists('My Error Message');
+ $this->assertSession()->statusMessageExists('My Warning Message');
// Test partial match.
- $this->assertStatusMessageExists('My Status');
+ $this->assertSession()->statusMessageExists('My Status');
// Test with second arg.
- $this->assertStatusMessageExists('My Status Message', 'status');
- $this->assertStatusMessageExists('My Error Message', 'error');
- $this->assertStatusMessageExists('My Warning Message', 'warning');
+ $this->assertSession()->statusMessageExists('My Status Message', 'status');
+ $this->assertSession()->statusMessageExists('My Error Message', 'error');
+ $this->assertSession()->statusMessageExists('My Warning Message', 'warning');
// Test with no first arg.
- $this->assertStatusMessageExists(NULL, 'status');
- $this->assertStatusMessageExists(NULL, 'error');
- $this->assertStatusMessageExists(NULL, 'warning');
+ $this->assertSession()->statusMessageExists(NULL, 'status');
+ $this->assertSession()->statusMessageExists(NULL, 'error');
+ $this->assertSession()->statusMessageExists(NULL, 'warning');
// Test negative assertions.
- $this->assertStatusMessageNotExists('My Status Message is fake');
- $this->assertStatusMessageNotExists('My Status Message is fake', 'status');
- $this->assertStatusMessageNotExists('My Error Message', 'status');
- $this->assertStatusMessageNotExists('My Status Message', 'error');
+ $this->assertSession()->statusMessageNotExists('My Status Message is fake');
+ $this->assertSession()->statusMessageNotExists('My Status Message is fake', 'status');
+ $this->assertSession()->statusMessageNotExists('My Error Message', 'status');
+ $this->assertSession()->statusMessageNotExists('My Status Message', 'error');
// Check that special characters get handled correctly.
- $this->assertStatusMessageExists('This has " in the middle');
- $this->assertStatusMessageExists('This has \' in the middle');
- $this->assertStatusMessageExists('Thismarkup will be escaped');
- $this->assertStatusMessageExists('Peaches & cream');
- $this->assertStatusMessageNotExists('Peaches & cream');
+ $this->assertSession()->statusMessageExists('This has " in the middle');
+ $this->assertSession()->statusMessageExists('This has \' in the middle');
+ $this->assertSession()->statusMessageExists('Thismarkup will be escaped');
+ $this->assertSession()->statusMessageExists('Peaches & cream');
+ $this->assertSession()->statusMessageNotExists('Peaches & cream');
// Test with bad message type.
$this->expectException(\InvalidArgumentException::class);
- $this->assertStatusMessageExists('Any old message', 'something bad');
+ $this->assertSession()->statusMessageExists('Any old message', 'something bad');
}
}
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/MessageCommandTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/MessageCommandTest.php
index 8867a69ae7..013aae6d7c 100644
--- a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/MessageCommandTest.php
+++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/MessageCommandTest.php
@@ -3,7 +3,6 @@
namespace Drupal\FunctionalJavascriptTests\Ajax;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
-use Drupal\Tests\AssertJavascriptStatusMessageTrait;
/**
* Tests adding messages via AJAX command.
@@ -12,8 +11,6 @@
*/
class MessageCommandTest extends WebDriverTestBase {
- use AssertJavascriptStatusMessageTrait;
-
/**
* {@inheritdoc}
*/
@@ -80,53 +77,52 @@ public function testMessageCommand() {
}
/**
- * Tests AssertJavascriptStatusMessageTrait.
+ * Tests methods in JsWebAssert related to status messages.
*/
- public function testAssertJavascriptStatusMessageTrait() {
+ public function testJsStatusMessageAssertions() {
$page = $this->getSession()->getPage();
- $assert_session = $this->assertSession();
$this->drupalGet('ajax-test/message');
$page->pressButton('Make Message In Default Location');
- $this->assertStatusMessageVisibleAfterWait('I am a message in the default location.');
+ $this->assertSession()->statusMessageVisibleAfterWait('I am a message in the default location.');
$page->pressButton('Make Message In Alternate Location');
- $this->assertStatusMessageVisibleAfterWait('I am a message in an alternate location.', 'status');
+ $this->assertSession()->statusMessageVisibleAfterWait('I am a message in an alternate location.', 'status');
$page->pressButton('Make Warning Message');
- $this->assertStatusMessageVisibleAfterWait('I am a warning message in the default location.', 'warning');
+ $this->assertSession()->statusMessageVisibleAfterWait('I am a warning message in the default location.', 'warning');
// Reload and test some negative assertions.
$this->drupalGet('ajax-test/message');
$page->pressButton('Make Message In Default Location');
// Use message that is not on page.
- $this->assertNoStatusMessageAfterWait('This is not a real message');
+ $this->assertSession()->statusMessageNotVisibleAfterWait('This is not a real message');
$page->pressButton('Make Message In Alternate Location');
// Use message that exists but has the wrong type.
- $this->assertNoStatusMessageAfterWait('I am a message in an alternate location.', 'warning');
+ $this->assertSession()->statusMessageNotVisibleAfterWait('I am a message in an alternate location.', 'warning');
// Test partial match.
$page->pressButton('Make Warning Message');
- $this->assertStatusMessageVisibleAfterWait('I am a warning');
+ $this->assertSession()->statusMessageVisibleAfterWait('I am a warning');
// One more reload to try with different arg combinations.
$this->drupalGet('ajax-test/message');
$page->pressButton('Make Message In Default Location');
- $this->assertStatusMessageVisibleAfterWait();
+ $this->assertSession()->statusMessageVisibleAfterWait();
$page->pressButton('Make Message In Alternate Location');
- $this->assertNoStatusMessageAfterWait(NULL, 'error');
+ $this->assertSession()->statusMessageNotVisibleAfterWait(NULL, 'error');
$page->pressButton('Make Warning Message');
- $this->assertStatusMessageVisibleAfterWait(NULL, 'warning');
+ $this->assertSession()->statusMessageVisibleAfterWait(NULL, 'warning');
// Test with bad message type.
$this->expectException(\InvalidArgumentException::class);
- $this->assertStatusMessageVisibleAfterWait('Any old message', 'something bad');
+ $this->assertSession()->statusMessageVisibleAfterWait('Any old message', 'something bad');
}
/**
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
index e9e1d9cdec..988b958849 100644
--- a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
+++ b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
@@ -523,4 +523,97 @@ public static function isExceptionNotClickable(Exception $exception): bool {
return (bool) preg_match('/not (clickable|interactable|visible)/', $exception->getMessage());
}
+ /**
+ * Asserts that a status message is visible after wait.
+ *
+ * @param string|null $message
+ * The optional message or partial message to assert.
+ * @param string|null $type
+ * The optional message type: status, error, or warning.
+ */
+ public function statusMessageVisibleAfterWait(?string $message = NULL, ?string $type = NULL): void {
+ $selector = $this->buildJavascriptStatusMessageSelector($message, $type);
+ $status_message_element = $this->waitForElementVisible('xpath', $selector);
+ if ($message) {
+ $failure_message = sprintf('A %s message containing the text "%s" does not appear on this page, but it should.', $type, $message);
+ }
+ else {
+ $failure_message = sprintf('A %s message does not appear on this page, but it should.', $type);
+ }
+ $this->assert(!is_null($status_message_element), $failure_message);
+ }
+
+ /**
+ * Asserts that a status message is not present after wait.
+ *
+ * @param string|null $message
+ * The optional message or partial message to assert.
+ * @param string|null $type
+ * The optional message type: status, error, or warning.
+ */
+ public function statusMessageNotVisibleAfterWait(?string $message = NULL, ?string $type = NULL): void {
+ $selector = $this->buildJavascriptStatusMessageSelector($message, $type);
+ $status_message_element = $this->waitForElementVisible('xpath', $selector);
+ if ($message) {
+ $failure_message = sprintf('A %s message containing the text "%s" appears on this page, but it should not.', $type, $message);
+ }
+ else {
+ $failure_message = sprintf('A %s message appears on this page, but it should not.', $type);
+ }
+ $this->assert(is_null($status_message_element), $failure_message);
+ }
+
+ /**
+ * Builds a xpath selector for a message with given type and text.
+ *
+ * The selector is designed to work with the Drupal.theme.message
+ * template defined in message.js in addition to status-messages.html.twig
+ * in the system module.
+ *
+ * @param string|null $message
+ * The optional message or partial message to assert.
+ * @param string|null $type
+ * The optional message type: status, error, or warning.
+ *
+ * @return string
+ * The xpath selector for the message.
+ *
+ * @throws \InvalidArgumentException
+ * Thrown when $type is not an allowed type.
+ */
+ public function buildJavascriptStatusMessageSelector(?string $message = NULL, ?string $type = NULL): string {
+ $allowed_types = [
+ 'status',
+ 'error',
+ 'warning',
+ NULL,
+ ];
+ if (!in_array($type, $allowed_types, TRUE)) {
+ throw new \InvalidArgumentException("The allowed status message types are 'status', 'error', 'warning'. Pass NULL to match any status message type.");
+ }
+
+ if ($type) {
+ $class = 'messages--' . $type;
+ }
+ else {
+ $class = 'messages__wrapper';
+ }
+
+ if ($message) {
+ $js_selector = $this->buildXPathQuery('//div[contains(@class, :class) and contains(., :message)]', [
+ ':class' => $class,
+ ':message' => $message,
+ ]);
+ }
+ else {
+ $js_selector = $this->buildXPathQuery('//div[contains(@class, :class)]', [
+ ':class' => $class,
+ ]);
+ }
+
+ // We select based on WebAssert::buildStatusMessageSelector() or the
+ // js_selector we have just built.
+ return $this->buildStatusMessageSelector($message, $type) . ' | ' . $js_selector;
+ }
+
}
diff --git a/core/tests/Drupal/Tests/AssertJavascriptStatusMessageTrait.php b/core/tests/Drupal/Tests/AssertJavascriptStatusMessageTrait.php
deleted file mode 100644
index f019e98bd7..0000000000
--- a/core/tests/Drupal/Tests/AssertJavascriptStatusMessageTrait.php
+++ /dev/null
@@ -1,95 +0,0 @@
-buildJavascriptStatusMessageSelector($message, $type);
- $this->assertNotEmpty($this->assertSession()->waitForElementVisible('xpath', $selector));
- }
-
- /**
- * Asserts that a status message is not present after wait.
- *
- * @param string|null $message
- * The optional message or partial message to assert.
- * @param string|null $type
- * The optional message type: status, error, or warning.
- */
- protected function assertNoStatusMessageAfterWait(?string $message = NULL, ?string $type = NULL): void {
- $selector = $this->buildJavascriptStatusMessageSelector($message, $type);
- $this->assertSession()->assertNoElementAfterWait('xpath', $selector);
- }
-
- /**
- * Builds a xpath selector for a message with given type and text.
- *
- * The selector is designed to work with the Drupal.theme.message
- * template defined in message.js in addition to status-messages.html.twig
- * in the system module.
- *
- * @param string|null $message
- * The optional message or partial message to assert.
- * @param string|null $type
- * The optional message type: status, error, or warning.
- *
- * @return string
- * The xpath selector for the message.
- *
- * @throws \InvalidArgumentException
- * Thrown when $type is not an allowed type.
- */
- protected function buildJavascriptStatusMessageSelector(?string $message = NULL, ?string $type = NULL): string {
- $allowed_types = [
- 'status',
- 'error',
- 'warning',
- NULL,
- ];
- if (!in_array($type, $allowed_types, TRUE)) {
- throw new \InvalidArgumentException("The allowed status message types are 'status', 'error', 'warning'. Pass NULL to match any status message type.");
- }
-
- if ($type) {
- $class = 'messages--' . $type;
- }
- else {
- $class = 'messages__wrapper';
- }
-
- if ($message) {
- $js_selector = $this->assertSession()->buildXPathQuery('//div[contains(@class, :class) and contains(., :message)]', [
- ':class' => $class,
- ':message' => $message,
- ]);
- }
- else {
- $js_selector = $this->assertSession()->buildXPathQuery('//div[contains(@class, :class)]', [
- ':class' => $class,
- ]);
- }
-
- // We select based on the AssertStatusMessageTrait or the js_selector we
- // have just built.
- return $this->buildStatusMessageSelector($message, $type) . ' | ' . $js_selector;
- }
-
-}
diff --git a/core/tests/Drupal/Tests/AssertStatusMessageTrait.php b/core/tests/Drupal/Tests/AssertStatusMessageTrait.php
deleted file mode 100644
index 3744fbb82b..0000000000
--- a/core/tests/Drupal/Tests/AssertStatusMessageTrait.php
+++ /dev/null
@@ -1,103 +0,0 @@
-buildStatusMessageSelector($message, $type);
- $this->assertSession()->elementExists('xpath', $selector);
- }
-
- /**
- * Asserts that a status message does not exist.
- *
- * @param string|null $message
- * The optional message or partial message to assert.
- * @param string|null $type
- * The optional message type: status, error, or warning.
- */
- protected function assertStatusMessageNotExists(?string $message = NULL, ?string $type = NULL): void {
- $selector = $this->buildStatusMessageSelector($message, $type);
- $this->assertSession()->elementNotExists('xpath', $selector);
- }
-
- /**
- * Builds a xpath selector for a message with given type and text.
- *
- * The selector is designed to work with the status-messages.html.twig
- * template in the system module.
- *
- * See Drupal\Core\Render\Element\StatusMessages for aria label definition.
- *
- * @param string|null $message
- * The optional message or partial message to assert.
- * @param string|null $type
- * The optional message type: status, error, or warning.
- *
- * @return string
- * The xpath selector for the message.
- *
- * @throws \InvalidArgumentException
- * Thrown when $type is not an allowed type.
- */
- protected function buildStatusMessageSelector(?string $message = NULL, ?string $type = NULL): string {
- $allowed_types = [
- 'status',
- 'error',
- 'warning',
- NULL,
- ];
- if (!in_array($type, $allowed_types, TRUE)) {
- throw new \InvalidArgumentException("The allowed status message types are 'status', 'error', 'warning'. Pass NULL to match any status message type.");
- }
- $selector = '//div[@data-drupal-messages]';
- $aria_label = NULL;
- switch ($type) {
- case 'status':
- $aria_label = 'Status message';
- break;
-
- case 'error':
- $aria_label = 'Error message';
- break;
-
- case 'warning':
- $aria_label = 'Warning message';
- }
-
- if ($message && $aria_label) {
- $selector = $this->assertSession()->buildXPathQuery($selector . '//div[contains(@aria-label, :aria_label) and contains(., :message)]', [
- ':aria_label' => $aria_label,
- ':message' => $message,
- ]);
- }
- elseif ($message) {
- $selector = $this->assertSession()->buildXPathQuery($selector . '//div[contains(., :message)]', [
- ':message' => $message,
- ]);
- }
- elseif ($aria_label) {
- $selector = $this->assertSession()->buildXPathQuery($selector . '//div[@aria-label=:aria_label]', [
- ':aria_label' => $aria_label,
- ]);
- }
-
- return $selector;
- }
-
-}
diff --git a/core/tests/Drupal/Tests/WebAssert.php b/core/tests/Drupal/Tests/WebAssert.php
index a5d80a6e3c..96429f653a 100644
--- a/core/tests/Drupal/Tests/WebAssert.php
+++ b/core/tests/Drupal/Tests/WebAssert.php
@@ -1125,4 +1125,94 @@ public function checkboxNotChecked($field, TraversableElement $container = NULL)
return parent::checkboxNotChecked($field, $container);
}
+ /**
+ * Asserts that a status message exists.
+ *
+ * @param string|null $message
+ * The optional message or partial message to assert.
+ * @param string|null $type
+ * The optional message type: status, error, or warning.
+ */
+ public function statusMessageExists(?string $message = NULL, ?string $type = NULL): void {
+ $selector = $this->buildStatusMessageSelector($message, $type);
+ $this->elementExists('xpath', $selector);
+ }
+
+ /**
+ * Asserts that a status message does not exist.
+ *
+ * @param string|null $message
+ * The optional message or partial message to assert.
+ * @param string|null $type
+ * The optional message type: status, error, or warning.
+ */
+ public function statusMessageNotExists(?string $message = NULL, ?string $type = NULL): void {
+ $selector = $this->buildStatusMessageSelector($message, $type);
+ $this->elementNotExists('xpath', $selector);
+ }
+
+ /**
+ * Builds a xpath selector for a message with given type and text.
+ *
+ * The selector is designed to work with the status-messages.html.twig
+ * template in the system module.
+ *
+ * See Drupal\Core\Render\Element\StatusMessages for aria label definition.
+ *
+ * @param string|null $message
+ * The optional message or partial message to assert.
+ * @param string|null $type
+ * The optional message type: status, error, or warning.
+ *
+ * @return string
+ * The xpath selector for the message.
+ *
+ * @throws \InvalidArgumentException
+ * Thrown when $type is not an allowed type.
+ */
+ public function buildStatusMessageSelector(?string $message = NULL, ?string $type = NULL): string {
+ $allowed_types = [
+ 'status',
+ 'error',
+ 'warning',
+ NULL,
+ ];
+ if (!in_array($type, $allowed_types, TRUE)) {
+ throw new \InvalidArgumentException("The allowed status message types are 'status', 'error', 'warning'. Pass NULL to match any status message type.");
+ }
+ $selector = '//div[@data-drupal-messages]';
+ $aria_label = NULL;
+ switch ($type) {
+ case 'status':
+ $aria_label = 'Status message';
+ break;
+
+ case 'error':
+ $aria_label = 'Error message';
+ break;
+
+ case 'warning':
+ $aria_label = 'Warning message';
+ }
+
+ if ($message && $aria_label) {
+ $selector = $this->buildXPathQuery($selector . '//div[contains(@aria-label, :aria_label) and contains(., :message)]', [
+ ':aria_label' => $aria_label,
+ ':message' => $message,
+ ]);
+ }
+ elseif ($message) {
+ $selector = $this->buildXPathQuery($selector . '//div[contains(., :message)]', [
+ ':message' => $message,
+ ]);
+ }
+ elseif ($aria_label) {
+ $selector = $this->buildXPathQuery($selector . '//div[@aria-label=:aria_label]', [
+ ':aria_label' => $aria_label,
+ ]);
+ }
+
+ return $selector;
+ }
+
}