diff --git a/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php b/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php
index 35ccf0c..7bb0fb1 100644
--- a/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php
+++ b/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php
@@ -88,4 +88,14 @@ public function error() {
     ];
   }
 
+  /**
+   * Renders a page with encoded markup.
+   *
+   * @return array
+   *   A render array as expected by drupal_render()
+   */
+  public function renderEncodedMarkup() {
+    return ['#plain_text' => 'Bad html <script>alert(123);</script>'];
+  }
+
 }
diff --git a/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml b/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml
index a2d5ed5..cbcf6d8 100644
--- a/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml
+++ b/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml
@@ -58,3 +58,11 @@ test_page_test.error:
     code: 200
   requirements:
     _access: 'TRUE'
+
+test_page_test.encoded:
+  path: '/test-encoded'
+  defaults:
+    _title: 'Page with encoded HTML'
+    _controller: '\Drupal\test_page_test\Controller\Test::renderEncodedMarkup'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php b/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php
index 88b4092..2393f61 100644
--- a/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php
+++ b/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\FunctionalTests;
 
+use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Component\Utility\Xss;
 use Drupal\KernelTests\AssertLegacyTrait as BaseAssertLegacyTrait;
 
 /**
@@ -53,10 +55,17 @@ protected function assertElementNotPresent($css_selector) {
    *   Plain text to look for.
    *
    * @deprecated Scheduled for removal in Drupal 9.0.0.
-   *   Use $this->assertSession()->pageTextContains() or
-   *   $this->assertSession()->responseContains() instead.
+   *   Use instead:
+   *     - $this->assertSession()->responseContains() for non-HTML responses,
+   *       like XML or Json.
+   *     - $this->assertSession()->pageTextContains() for HTML responses. Unlike
+   *       the deprecated assertText(), the passed text should be HTML decoded,
+   *       exactly as a human sees it in the browser.
    */
   protected function assertText($text) {
+    // Cast MarkupInterface to string.
+    $text = (string) $text;
+
     $content_type = $this->getSession()->getResponseHeader('Content-type');
     // In case of a Non-HTML response (example: XML) check the original
     // response.
@@ -64,7 +73,7 @@ protected function assertText($text) {
       $this->assertSession()->responseContains($text);
     }
     else {
-      $this->assertSession()->pageTextContains($text);
+      $this->assertTextHelper($text, FALSE);
     }
   }
 
@@ -78,10 +87,17 @@ protected function assertText($text) {
    *   Plain text to look for.
    *
    * @deprecated Scheduled for removal in Drupal 9.0.0.
-   *   Use $this->assertSession()->pageTextNotContains() or
-   *   $this->assertSession()->responseNotContains() instead.
+   *   Use instead:
+   *     - $this->assertSession()->responseNotContains() for non-HTML responses,
+   *       like XML or Json.
+   *     - $this->assertSession()->pageTextNotContains() for HTML responses.
+   *       Unlike the deprecated assertNoText(), the passed text should be HTML
+   *       decoded, exactly as a human sees it in the browser.
    */
   protected function assertNoText($text) {
+    // Cast MarkupInterface to string.
+    $text = (string) $text;
+
     $content_type = $this->getSession()->getResponseHeader('Content-type');
     // In case of a Non-HTML response (example: XML) check the original
     // response.
@@ -89,11 +105,41 @@ protected function assertNoText($text) {
       $this->assertSession()->responseNotContains($text);
     }
     else {
-      $this->assertSession()->pageTextNotContains($text);
+      $this->assertTextHelper($text);
     }
   }
 
   /**
+   * Helper for assertText and assertNoText.
+   *
+   * @param string $text
+   *   Plain text to look for.
+   * @param bool $not_exists
+   *   (optional) TRUE if this text should not exist, FALSE if it should.
+   *   Defaults to TRUE.
+   *
+   * @return bool
+   *   TRUE on pass, FALSE on fail.
+   */
+  protected function assertTextHelper($text, $not_exists = TRUE) {
+    $args = ['@text' => $text];
+    $message = $not_exists ? new FormattableMarkup('"@text" not found', $args) : new FormattableMarkup('"@text" found', $args);
+
+    $raw_content = $this->getSession()->getPage()->getContent();
+    // Trying to simulate what the user sees, given that it removes all text
+    // inside the head tags, removes inline Javascript, fix all HTML entities,
+    // removes dangerous protocols and filtering out all HTML tags, as they are
+    // not visible in a normal browser.
+    $raw_content = preg_replace('@<head>(.+?)</head>@si', '', $raw_content);
+    $page_text = Xss::filter($raw_content, []);
+
+    $actual = $not_exists == (strpos($page_text, (string) $text) === FALSE);
+    $this->assertTrue($actual, $message);
+
+    return $actual;
+  }
+
+  /**
    * Passes if the text is found ONLY ONCE on the text version of the page.
    *
    * The text version is the equivalent of what a user would see when viewing
diff --git a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php
index d491e67..b0a53dd 100644
--- a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php
+++ b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\FunctionalTests;
 
+use Drupal\Component\Utility\Html;
 use Drupal\Core\Url;
 use Drupal\Tests\BrowserTestBase;
 
@@ -111,4 +112,15 @@ public function testError() {
     $this->drupalGet('test-error');
   }
 
+  /**
+   * Tests legacy asserts.
+   */
+  public function testLegacyAsserts() {
+    $this->drupalGet('test-encoded');
+    $dangerous = 'Bad html <script>alert(123);</script>';
+    $sanitized = Html::escape($dangerous);
+    $this->assertNoText($dangerous);
+    $this->assertText($sanitized);
+  }
+
 }
