diff --git a/composer.json b/composer.json
index 783b1461b8..e197d6e9d2 100644
--- a/composer.json
+++ b/composer.json
@@ -22,10 +22,10 @@
         "drupal/coder": "^8.3.10",
         "instaclick/php-webdriver": "^1.4.1",
         "mikey179/vfsstream": "^1.6.8",
-        "phpunit/phpunit": "^9.5",
+        "phpunit/phpunit": "^9.5 || dev-master",
         "phpspec/prophecy-phpunit": "^2",
         "symfony/css-selector": "^4.4",
-        "symfony/phpunit-bridge": "^5.4",
+        "symfony/phpunit-bridge": "^5.4 || ^6",
         "symfony/var-dumper": "^5.4",
         "symfony/error-handler": "^4.4",
         "justinrainbow/json-schema": "^5.2",
@@ -103,8 +103,9 @@
         "pre-autoload-dump": "Drupal\\Core\\Composer\\Composer::preAutoloadDump",
         "drupal-phpunit-upgrade-check": "Drupal\\Core\\Composer\\Composer::upgradePHPUnit",
         "drupal-phpunit-upgrade": [
-            "@composer update phpunit/phpunit --with-dependencies --no-progress",
-            "@composer require phpspec/prophecy-phpunit:^2 --no-progress --no-suggest"
+            "@composer remove phpunit/phpunit phpspec/prophecy-phpunit phpspec/prophecy --dev",
+            "@composer require phpunit/phpunit:\"dev-master as 9.10.99\" --dev --no-progress --update-with-all-dependencies --ignore-platform-req php",
+            "@composer update -W symfony/phpunit-bridge"
         ],
         "post-update-cmd": [
             "Drupal\\Composer\\Composer::generateMetapackages"
diff --git a/core/drupalci.yml b/core/drupalci.yml
index 413272eff3..7c1e39b3c8 100644
--- a/core/drupalci.yml
+++ b/core/drupalci.yml
@@ -8,42 +8,42 @@ build:
   assessment:
     testing:
       # Run code quality checks.
-      container_command.commit-checks:
-        commands:
-          - "core/scripts/dev/commit-code-check.sh --drupalci"
-        halt-on-fail: true
+#      container_command.commit-checks:
+#        commands:
+#          - "core/scripts/dev/commit-code-check.sh --drupalci"
+#        halt-on-fail: true
       # run_tests task is executed several times in order of performance speeds.
       # halt-on-fail can be set on the run_tests tasks in order to fail fast.
       # suppress-deprecations is false in order to be alerted to usages of
       # deprecated code.
       run_tests.phpunit:
         types: 'PHPUnit-Unit'
-        testgroups: '--all'
+        testgroups: 'Entity'
         suppress-deprecations: false
         halt-on-fail: false
       run_tests.kernel:
         types: 'PHPUnit-Kernel'
-        testgroups: '--all'
-        suppress-deprecations: false
-        halt-on-fail: false
-      run_tests.build:
-        # Limit concurrency due to disk space concerns.
-        concurrency: 15
-        types: 'PHPUnit-Build'
-        testgroups: '--all'
+        testgroups: 'image'
         suppress-deprecations: false
         halt-on-fail: false
+#      run_tests.build:
+#        # Limit concurrency due to disk space concerns.
+#        concurrency: 15
+#        types: 'PHPUnit-Build'
+#        testgroups: '--all'
+#        suppress-deprecations: false
+#        halt-on-fail: false
       run_tests.functional:
         types: 'PHPUnit-Functional'
-        testgroups: '--all'
+        testgroups: 'image'
         suppress-deprecations: false
         halt-on-fail: false
       run_tests.javascript:
         concurrency: 15
         types: 'PHPUnit-FunctionalJavascript'
-        testgroups: '--all'
+        testgroups: 'image'
         suppress-deprecations: false
         halt-on-fail: false
-      # Run nightwatch testing.
-      # @see https://www.drupal.org/project/drupal/issues/2869825
-      nightwatchjs: {}
+#      # Run nightwatch testing.
+#      # @see https://www.drupal.org/project/drupal/issues/2869825
+#      nightwatchjs: {}
diff --git a/core/lib/Drupal/Core/Composer/Composer.php b/core/lib/Drupal/Core/Composer/Composer.php
index b812636423..8f030865e5 100644
--- a/core/lib/Drupal/Core/Composer/Composer.php
+++ b/core/lib/Drupal/Core/Composer/Composer.php
@@ -332,7 +332,7 @@ public static function upgradePHPUnit(Event $event) {
    *   TRUE if the PHPUnit needs to be upgraded, FALSE if not.
    */
   public static function upgradePHPUnitCheck($phpunit_version) {
-    return !(version_compare(PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION, '7.4') >= 0 && version_compare($phpunit_version, '9.0') < 0);
+    return !(version_compare(PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION, '8.1') >= 0 && version_compare($phpunit_version, '10') < 0);
   }
 
 }
diff --git a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php
index 84171a17b4..239145c7d9 100644
--- a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php
+++ b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Database\Database;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\Tests\Listeners\SimpletestUiPrinter;
+use Drupal\TestTools\PhpUnitCompatibility\RunnerVersion;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Process\PhpExecutableFinder;
 
@@ -145,10 +146,14 @@ public function runCommand(array $unescaped_test_classnames, $phpunit_file, &$st
       $phpunit_bin,
       '--log-junit',
       escapeshellarg($phpunit_file),
-      '--printer',
-      escapeshellarg(SimpletestUiPrinter::class),
     ];
 
+    // @todo Remove below when PHPUnit 9 is no longer supported.
+    if (RunnerVersion::getMajor() < 10) {
+      $command[] = '--printer';
+      $command[] = escapeshellarg(SimpletestUiPrinter::class);
+    }
+
     // Optimized for running a single test.
     if (count($unescaped_test_classnames) == 1) {
       $class = new \ReflectionClass($unescaped_test_classnames[0]);
diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist
index 53a6f7a474..66bbbf0c78 100644
--- a/core/phpunit.xml.dist
+++ b/core/phpunit.xml.dist
@@ -12,9 +12,9 @@
          beStrictAboutOutputDuringTests="true"
          beStrictAboutChangesToGlobalState="true"
          failOnWarning="true"
-         printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter"
          cacheResult="false"
-         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
+         cacheDirectory=".phpunit.cache"
+         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd">
   <php>
     <!-- Set error reporting to E_ALL. -->
     <ini name="error_reporting" value="32767"/>
diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh
index 17ec49b9a4..7b82f5c0a4 100755
--- a/core/scripts/run-tests.sh
+++ b/core/scripts/run-tests.sh
@@ -148,8 +148,9 @@
   exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
 }
 
+simpletest_script_print("PHP version: " . phpversion() . " - PHPUnit version: " . Version::id() . "\n", SIMPLETEST_SCRIPT_COLOR_PASS);
 if (!Composer::upgradePHPUnitCheck(Version::id())) {
-  simpletest_script_print_error("PHPUnit testing framework version 9 or greater is required when running on PHP 7.4 or greater. Run the command 'composer run-script drupal-phpunit-upgrade' in order to fix this.");
+  simpletest_script_print_error("PHPUnit testing framework version 10 or greater is required when running on PHP 8.1 or greater. Run the command 'composer run-script drupal-phpunit-upgrade' in order to fix this.");
   exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
 }
 
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php b/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php
index 7f92b9ed00..101930018e 100644
--- a/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php
+++ b/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php
@@ -4,6 +4,7 @@
 
 use Behat\Mink\Exception\DriverException;
 use Drupal\Tests\BrowserTestBase;
+use Drupal\TestTools\PhpUnitCompatibility\RunnerVersion;
 use PHPUnit\Runner\BaseTestRunner;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -92,10 +93,14 @@ protected function initFrontPage() {
    */
   protected function tearDown(): void {
     if ($this->mink) {
-      $status = $this->getStatus();
-      if ($status === BaseTestRunner::STATUS_ERROR || $status === BaseTestRunner::STATUS_WARNING || $status === BaseTestRunner::STATUS_FAILURE) {
-        // Ensure we capture the output at point of failure.
-        @$this->htmlOutput();
+      // @todo ::getStatus was removed from PHPUnit 10, we probably need to
+      // intercept an event instead.
+      if (RunnerVersion::getMajor() < 10) {
+        $status = $this->getStatus();
+        if ($status === BaseTestRunner::STATUS_ERROR || $status === BaseTestRunner::STATUS_WARNING || $status === BaseTestRunner::STATUS_FAILURE) {
+          // Ensure we capture the output at point of failure.
+          @$this->htmlOutput();
+        }
       }
       // Wait for all requests to finish. It is possible that an AJAX request is
       // still on-going.
diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/DrupalStandards.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/DrupalStandards.php
new file mode 100644
index 0000000000..c4387eb002
--- /dev/null
+++ b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/DrupalStandards.php
@@ -0,0 +1,75 @@
+<?php declare(strict_types=1);
+
+namespace Drupal\TestTools\PhpUnitCompatibility\PhpUnit10;
+
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\UnitTestCase;
+use Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\DrupalStandardsSubscriber\BeforeFirstTestMethodCalledSubscriber;
+use PHPUnit\Event\Facade;
+use PHPUnit\Event\Test\BeforeFirstTestMethodCalled;
+
+/**
+ * @internal
+ */
+final class DrupalStandards {
+
+  /**
+   * The singleton instance.
+   *
+   * @var self
+   */
+  private static ?self $instance = NULL;
+
+  /**
+   * @throws \PHPUnit\Event\EventFacadeIsSealedException
+   * @throws \PHPUnit\Util\Exception
+   * @throws \PHPUnit\Event\UnknownSubscriberTypeException
+   * @throws \RuntimeException
+   */
+  private function __construct() {
+    Facade::registerSubscriber(new BeforeFirstTestMethodCalledSubscriber($this));
+  }
+
+  /**
+   * @todo
+   *
+   * @throws \PHPUnit\Event\EventFacadeIsSealedException
+   * @throws \PHPUnit\Util\Exception
+   * @throws \PHPUnit\Event\UnknownSubscriberTypeException
+   * @throws \RuntimeException
+   */
+  public static function init(): void {
+    if (self::$instance === NULL) {
+      self::$instance = new self();
+    }
+  }
+
+  /**
+   * @todo
+   */
+  public static function isEnabled(): bool {
+    return self::$instance !== NULL;
+  }
+
+  /**
+   * @todo
+   */
+  public function beforeFirstTestMethodCalledSubscriber(BeforeFirstTestMethodCalled $event): void {
+    // Reflect the test class.
+    $class = new \ReflectionClass($event->testClassName());
+
+    // Check for component tests extending a core test.
+    if (substr($event->testClassName(), 0, 22) == 'Drupal\Tests\Component') {
+      if ($class instanceof BrowserTestBase || $class instanceof KernelTestBase || $class instanceof UnitTestCase) {
+        throw new \LogicException('Component test ' . $event->testClassName() . ' should not extend a core test base class');
+      }
+    }
+
+    // Check for incorrect visibility of the $modules property.
+    if ($class->hasProperty('modules') && !$class->getProperty('modules')->isProtected()) {
+      throw new \LogicException('The ' . $event->testClassName() . '::$modules property must be declared protected');
+    }
+  }
+
+}
diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/DrupalStandardsSubscriber/BeforeFirstTestMethodCalledSubscriber.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/DrupalStandardsSubscriber/BeforeFirstTestMethodCalledSubscriber.php
new file mode 100644
index 0000000000..bb055378ed
--- /dev/null
+++ b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/DrupalStandardsSubscriber/BeforeFirstTestMethodCalledSubscriber.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+
+namespace Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\DrupalStandardsSubscriber;
+
+use PHPUnit\Event\Test\BeforeFirstTestMethodCalled;
+use PHPUnit\Event\Test\BeforeFirstTestMethodCalledSubscriber as SubscriberInterface;
+
+/**
+ * @internal
+ */
+final class BeforeFirstTestMethodCalledSubscriber extends Subscriber implements SubscriberInterface {
+
+  public function notify(BeforeFirstTestMethodCalled $event): void {
+    $this->standards()->beforeFirstTestMethodCalledSubscriber($event);
+  }
+
+}
diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/DrupalStandardsSubscriber/Subscriber.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/DrupalStandardsSubscriber/Subscriber.php
new file mode 100644
index 0000000000..8eef5dfc2e
--- /dev/null
+++ b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/DrupalStandardsSubscriber/Subscriber.php
@@ -0,0 +1,22 @@
+<?php declare(strict_types=1);
+
+namespace Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\DrupalStandardsSubscriber;
+
+use Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\DrupalStandards;
+
+/**
+ * @internal
+ */
+abstract class Subscriber {
+
+  private DrupalStandards $standards;
+
+  public function __construct(DrupalStandards $standards) {
+    $this->standards = $standards;
+  }
+
+  protected function standards(): DrupalStandards {
+    return $this->standards;
+  }
+
+}
diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/HtmlOutputLogger.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/HtmlOutputLogger.php
new file mode 100644
index 0000000000..02162e9c83
--- /dev/null
+++ b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/HtmlOutputLogger.php
@@ -0,0 +1,119 @@
+<?php declare(strict_types=1);
+
+namespace Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\Logging;
+
+use Drupal\Component\Utility\Html;
+use Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\Logging\Subscriber\TestRunnerFinishedSubscriber;
+use Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\Logging\Subscriber\TestRunnerStartedSubscriber;
+use PHPUnit\Event\Facade;
+use PHPUnit\Event\TestRunner\Finished as TestRunnerFinished;
+use PHPUnit\Event\TestRunner\Started as TestRunnerStarted;
+use PHPUnit\TextUI\DefaultResultPrinter;
+
+/**
+ * @internal
+ */
+final class HtmlOutputLogger extends DefaultResultPrinter {
+
+  /**
+   * The singleton instance.
+   *
+   * @var self
+   */
+  private static ?self $instance = NULL;
+
+  /**
+   * File to write html links to.
+   *
+   * @var string
+   */
+  private string $browserOutputFile;
+
+  /**
+   * @throws \PHPUnit\Event\EventFacadeIsSealedException
+   * @throws \PHPUnit\Util\Exception
+   * @throws \PHPUnit\Event\UnknownSubscriberTypeException
+   * @throws \RuntimeException
+   */
+  private function __construct(string $browserTestOutputDirectory) {
+    $this->browserOutputFile = $this->determineBrowserOutputFile($browserTestOutputDirectory);
+    parent::__construct($this->browserOutputFile);
+    Facade::registerSubscriber(new TestRunnerFinishedSubscriber($this));
+    Facade::registerSubscriber(new TestRunnerStartedSubscriber($this));
+  }
+
+  /**
+   * @todo
+   *
+   * @throws \PHPUnit\Event\EventFacadeIsSealedException
+   * @throws \PHPUnit\Util\Exception
+   * @throws \PHPUnit\Event\UnknownSubscriberTypeException
+   * @throws \RuntimeException
+   */
+  public static function init(string $browserTestOutputDirectory): void {
+    if (self::$instance === NULL) {
+      self::$instance = new self($browserTestOutputDirectory);
+    }
+  }
+
+  /**
+   * @todo
+   */
+  public static function isEnabled(): bool {
+    return self::$instance !== NULL;
+  }
+
+  /**
+   * @todo
+   *
+   * @throws \RuntimeException
+   */
+  public static function log(string $logEntry): void {
+    if (!self::isEnabled()) {
+      throw new \RuntimeException("HTML output is not enabled");
+    }
+    self::$instance->write($logEntry);
+  }
+
+  /**
+   * @todo
+   */
+  private function determineBrowserOutputFile(string $browserTestOutputDirectory): string {
+    // Convert to a canonicalized absolute pathname just in case the current
+    // working directory has changed.
+    if (($html_output_directory = realpath(rtrim($browserTestOutputDirectory, '/'))) === FALSE) {
+      throw new \RuntimeException("HTML output directory $browserTestOutputDirectory is not a writable directory");
+    }
+
+    if (($browserOutputFile = tempnam($html_output_directory, 'browser_output_')) === FALSE) {
+      throw new \RuntimeException("Unable to create a temporary file in $html_output_directory");
+    }
+
+    return $browserOutputFile;
+  }
+
+  /**
+   * Creates the file to list the HTML output created during the test run.
+   *
+   * @see \Drupal\Tests\BrowserTestBase::initBrowserOutputFile()
+   */
+  public function testRunnerStarted(TestRunnerStarted $event): void {
+    putenv('BROWSERTEST_OUTPUT_FILE=' . $this->browserOutputFile);
+  }
+
+  /**
+   * Prints the list of HTML output generated during the test.
+   */
+  public function testRunnerFinished(TestRunnerFinished $event): void {
+    $this->flush();
+    $contents = file_get_contents($this->browserOutputFile);
+    if ($contents) {
+      print "\n";
+      print "HTML output was generated\n";
+      print $contents;
+    }
+    // No need to keep the file around any more.
+    unlink($this->browserOutputFile);
+  }
+
+}
diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/Subscriber/Subscriber.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/Subscriber/Subscriber.php
new file mode 100644
index 0000000000..d2a29592b3
--- /dev/null
+++ b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/Subscriber/Subscriber.php
@@ -0,0 +1,22 @@
+<?php declare(strict_types=1);
+
+namespace Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\Logging\Subscriber;
+
+use Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\Logging\HtmlOutputLogger;
+
+/**
+ * @internal
+ */
+abstract class Subscriber
+{
+  private HtmlOutputLogger $logger;
+
+  public function __construct(HtmlOutputLogger $logger) {
+    $this->logger = $logger;
+  }
+
+  protected function logger(): HtmlOutputLogger {
+    return $this->logger;
+  }
+
+}
diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/Subscriber/TestRunnerFinishedSubscriber.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/Subscriber/TestRunnerFinishedSubscriber.php
new file mode 100644
index 0000000000..2e870f2955
--- /dev/null
+++ b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/Subscriber/TestRunnerFinishedSubscriber.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+
+namespace Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\Logging\Subscriber;
+
+use PHPUnit\Event\TestRunner\Finished;
+use PHPUnit\Event\TestRunner\FinishedSubscriber;
+
+/**
+ * @internal
+ */
+final class TestRunnerFinishedSubscriber extends Subscriber implements FinishedSubscriber
+{
+  public function notify(Finished $event): void {
+    $this->logger()->testRunnerFinished($event);
+  }
+}
diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/Subscriber/TestRunnerStartedSubscriber.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/Subscriber/TestRunnerStartedSubscriber.php
new file mode 100644
index 0000000000..503473bb63
--- /dev/null
+++ b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/Logging/Subscriber/TestRunnerStartedSubscriber.php
@@ -0,0 +1,16 @@
+<?php declare(strict_types=1);
+
+namespace Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\Logging\Subscriber;
+
+use PHPUnit\Event\TestRunner\Started;
+use PHPUnit\Event\TestRunner\StartedSubscriber;
+
+/**
+ * @internal
+ */
+final class TestRunnerStartedSubscriber extends Subscriber implements StartedSubscriber
+{
+  public function notify(Started $event): void {
+    $this->logger()->testRunnerStarted($event);
+  }
+}
diff --git a/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/TestCompatibilityTrait.php b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/TestCompatibilityTrait.php
new file mode 100644
index 0000000000..c759cd0045
--- /dev/null
+++ b/core/tests/Drupal/TestTools/PhpUnitCompatibility/PhpUnit10/TestCompatibilityTrait.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace Drupal\TestTools\PhpUnitCompatibility\PhpUnit10;
+
+/**
+ * Drupal's forward compatibility layer with multiple versions of PHPUnit.
+ */
+trait TestCompatibilityTrait {
+}
diff --git a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
index e0b85ef546..22c1fb67a0 100644
--- a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
+++ b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
@@ -4,6 +4,8 @@
 
 use Drupal\Component\Utility\Html;
 use Drupal\Core\Utility\Error;
+use Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\Logging\HtmlOutputLogger;
+use Drupal\TestTools\PhpUnitCompatibility\RunnerVersion;
 use Psr\Http\Message\RequestInterface;
 use Psr\Http\Message\ResponseInterface;
 
@@ -55,6 +57,8 @@
    * @var string
    *
    * @see \Drupal\Tests\Listeners\HtmlOutputPrinter
+   *
+   * @todo Remove when PHPUnit 9 is no longer supported.
    */
   protected $htmlOutputFile;
 
@@ -126,7 +130,13 @@ protected function htmlOutput($message = NULL) {
     // Do not use the file_url_generator service as the module_handler service
     // might not be available.
     $uri = $this->htmlOutputBaseUrl . '/sites/simpletest/browser_output/' . $html_output_filename;
-    file_put_contents($this->htmlOutputFile, $uri . "\n", FILE_APPEND);
+    // @todo Cleanup below when PHPUnit 9 is no longer supported.
+    if (RunnerVersion::getMajor() > 9) {
+      HtmlOutputLogger::log($uri . "\n");
+    }
+    else {
+      file_put_contents($this->htmlOutputFile, $uri . "\n", FILE_APPEND);
+    }
   }
 
   /**
@@ -136,11 +146,19 @@ protected function htmlOutput($message = NULL) {
    * URLs to has been created by \Drupal\Tests\Listeners\HtmlOutputPrinter.
    */
   protected function initBrowserOutputFile() {
-    $browser_output_file = getenv('BROWSERTEST_OUTPUT_FILE');
-    $this->htmlOutputEnabled = is_file($browser_output_file);
+    // @todo Cleanup below when PHPUnit 9 is no longer supported.
+    if (RunnerVersion::getMajor() > 9) {
+      $this->htmlOutputEnabled = HtmlOutputLogger::isEnabled();
+    }
+    else {
+      $browser_output_file = getenv('BROWSERTEST_OUTPUT_FILE');
+      $this->htmlOutputEnabled = is_file($browser_output_file);
+      if ($this->htmlOutputEnabled) {
+        $this->htmlOutputFile = $browser_output_file;
+      }
+    }
     $this->htmlOutputBaseUrl = getenv('BROWSERTEST_OUTPUT_BASE_URL') ?: $GLOBALS['base_url'];
     if ($this->htmlOutputEnabled) {
-      $this->htmlOutputFile = $browser_output_file;
       $this->htmlOutputClassName = str_replace("\\", "_", static::class);
       $this->htmlOutputDirectory = DRUPAL_ROOT . '/sites/simpletest/browser_output';
       // Do not use the file_system service so this method can be called before
diff --git a/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php b/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
index 8a85f29b31..0413616ac7 100644
--- a/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
+++ b/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
@@ -1,5 +1,7 @@
 <?php
 
+// @todo Remove this file when PHPUnit 9 is no longer supported.
+
 namespace Drupal\Tests\Listeners;
 
 use PHPUnit\Util\Test;
@@ -132,6 +134,8 @@ public static function getSkippedDeprecations() {
       "The \"PHPUnit\Framework\TestSuite\" class is considered internal This class is not covered by the backward compatibility promise for PHPUnit. It may change without further notice. You should not use it from \"Drupal\Tests\TestSuites\TestSuiteBase\".",
       // PHPUnit 9.
       "The \"PHPUnit\TextUI\DefaultResultPrinter\" class is considered internal This class is not covered by the backward compatibility promise for PHPUnit. It may change without further notice. You should not use it from \"Drupal\Tests\Listeners\HtmlOutputPrinter\".",
+      // PHPUnit 10.
+      'The withConsecutive() method has been deprecated. It will be removed in PHPUnit 11.',
     ];
   }
 
diff --git a/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListenerTrait.php b/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListenerTrait.php
index 6428bae39c..ef5e33a37d 100644
--- a/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListenerTrait.php
+++ b/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListenerTrait.php
@@ -1,5 +1,7 @@
 <?php
 
+// @todo Remove this file when PHPUnit 9 is no longer supported.
+
 namespace Drupal\Tests\Listeners;
 
 use Drupal\KernelTests\KernelTestBase;
diff --git a/core/tests/Drupal/Tests/Listeners/DrupalListener.php b/core/tests/Drupal/Tests/Listeners/DrupalListener.php
index 758124cf8b..4066791948 100644
--- a/core/tests/Drupal/Tests/Listeners/DrupalListener.php
+++ b/core/tests/Drupal/Tests/Listeners/DrupalListener.php
@@ -1,5 +1,7 @@
 <?php
 
+// @todo Remove this file when PHPUnit 9 is no longer supported.
+
 namespace Drupal\Tests\Listeners;
 
 use PHPUnit\Framework\TestListener;
diff --git a/core/tests/Drupal/Tests/Listeners/DrupalStandardsListenerTrait.php b/core/tests/Drupal/Tests/Listeners/DrupalStandardsListenerTrait.php
index aac9b3056b..7552764c05 100644
--- a/core/tests/Drupal/Tests/Listeners/DrupalStandardsListenerTrait.php
+++ b/core/tests/Drupal/Tests/Listeners/DrupalStandardsListenerTrait.php
@@ -1,5 +1,7 @@
 <?php
 
+// @todo Remove this file when PHPUnit 9 is no longer supported.
+
 namespace Drupal\Tests\Listeners;
 
 use PHPUnit\Framework\AssertionFailedError;
diff --git a/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinter.php b/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinter.php
index a85c320499..6793da3202 100644
--- a/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinter.php
+++ b/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinter.php
@@ -1,5 +1,7 @@
 <?php
 
+// @todo Remove this file when PHPUnit 9 is no longer supported.
+
 namespace Drupal\Tests\Listeners;
 
 use Drupal\TestTools\PhpUnitCompatibility\RunnerVersion;
@@ -9,12 +11,7 @@
 // dynamically load the base ResultPrinter class dependent on the PHPUnit runner
 // version.
 if (!class_exists(ResultPrinterBase::class, FALSE)) {
-  if (RunnerVersion::getMajor() < 9) {
-    class_alias('PHPUnit\TextUI\ResultPrinter', ResultPrinterBase::class);
-  }
-  else {
-    class_alias('PHPUnit\TextUI\DefaultResultPrinter', ResultPrinterBase::class);
-  }
+  class_alias('PHPUnit\TextUI\DefaultResultPrinter', ResultPrinterBase::class);
 }
 
 /**
diff --git a/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinterTrait.php b/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinterTrait.php
index 6cdd1e8002..8dda2181ba 100644
--- a/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinterTrait.php
+++ b/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinterTrait.php
@@ -1,5 +1,7 @@
 <?php
 
+// @todo Remove this file when PHPUnit 9 is no longer supported.
+
 namespace Drupal\Tests\Listeners;
 
 use Drupal\Component\Utility\Html;
diff --git a/core/tests/Drupal/Tests/Listeners/SimpletestUiPrinter.php b/core/tests/Drupal/Tests/Listeners/SimpletestUiPrinter.php
index 13383b4c31..3952595612 100644
--- a/core/tests/Drupal/Tests/Listeners/SimpletestUiPrinter.php
+++ b/core/tests/Drupal/Tests/Listeners/SimpletestUiPrinter.php
@@ -1,5 +1,7 @@
 <?php
 
+// @todo Remove this file when PHPUnit 9 is no longer supported.
+
 namespace Drupal\Tests\Listeners;
 
 /**
diff --git a/core/tests/Drupal/Tests/Traits/PhpUnitWarnings.php b/core/tests/Drupal/Tests/Traits/PhpUnitWarnings.php
index 4b4a2c323d..d1ebff8d30 100644
--- a/core/tests/Drupal/Tests/Traits/PhpUnitWarnings.php
+++ b/core/tests/Drupal/Tests/Traits/PhpUnitWarnings.php
@@ -48,6 +48,8 @@
     'assertDirectoryNotIsWritable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDirectoryIsNotWritable() instead.',
     'assertFileNotIsWritable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertFileIsNotWritable() instead.',
     'The at() matcher has been deprecated. It will be removed in PHPUnit 10. Please refactor your test to not rely on the order in which methods are invoked.',
+    // PHPUnit 10.
+    'The withConsecutive() method has been deprecated. It will be removed in PHPUnit 11.',
   ];
 
   /**
diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php
index 5f5b494cfc..9f517dbc07 100644
--- a/core/tests/bootstrap.php
+++ b/core/tests/bootstrap.php
@@ -9,6 +9,10 @@
 
 use Drupal\Component\Assertion\Handle;
 use Drupal\TestTools\PhpUnitCompatibility\PhpUnit8\ClassWriter;
+use Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\DrupalStandards;
+use Drupal\TestTools\PhpUnitCompatibility\PhpUnit10\Logging\HtmlOutputLogger;
+use Drupal\TestTools\PhpUnitCompatibility\RunnerVersion;
+use PHPUnit\Util\Filesystem;
 
 /**
  * Finds all valid extension directories recursively within a given directory.
@@ -179,3 +183,16 @@ class_alias('\Drupal\Tests\DocumentElement', '\Behat\Mink\Element\DocumentElemen
 // thrown if an assert fails, but this call does not turn runtime assertions on
 // if they weren't on already.
 Handle::register();
+
+if (RunnerVersion::getMajor() > 9) {
+  // Process Drupal standards checks on the tests.
+  DrupalStandards::init();
+
+  // Functional tests HTML output logging.
+  $browserTestOutputDirectory = getenv('BROWSERTEST_OUTPUT_DIRECTORY');
+  if ($browserTestOutputDirectory !== FALSE) {
+    if (Filesystem::createDirectory($browserTestOutputDirectory)) {
+      HtmlOutputLogger::init($browserTestOutputDirectory);
+    }
+  }
+}
