From 95ce49689c39f6574d2882b9452a2d8da832240b Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Fri, 11 Oct 2024 11:27:55 +0100
Subject: [PATCH 01/39] Added property for Mink session.

---
 core/tests/Drupal/KernelTests/KernelTestBase.php | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 34aca08f15a9..0cc4ba3f086a 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -4,6 +4,7 @@
 
 namespace Drupal\KernelTests;
 
+use Behat\Mink\Session;
 use Drupal\Component\FileCache\ApcuFileCacheBackend;
 use Drupal\Component\FileCache\FileCache;
 use Drupal\Component\FileCache\FileCacheFactory;
@@ -209,6 +210,15 @@ public function __construct(string $name) {
    */
   protected bool $usesSuperUserAccessPolicy;
 
+  /**
+   * The Mink session.
+   *
+   * This is lazily initialised.
+   *
+   * @var \Behat\Mink\Session|null
+   */
+  protected ?Session $minkSession;
+
   /**
    * Registers the dumper CLI handler when the DebugDump extension is enabled.
    */
-- 
GitLab


From b396578a5f6cdf951d7b6c91e27ecd1be247c2ad Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Fri, 11 Oct 2024 11:38:32 +0100
Subject: [PATCH 02/39] Added browser kit client for use in kernel tests.

---
 .../KernelTestHttpKernelBrowser.php           | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 core/tests/Drupal/TestTools/HttpKernel/KernelTestHttpKernelBrowser.php

diff --git a/core/tests/Drupal/TestTools/HttpKernel/KernelTestHttpKernelBrowser.php b/core/tests/Drupal/TestTools/HttpKernel/KernelTestHttpKernelBrowser.php
new file mode 100644
index 000000000000..37e6eb5aa218
--- /dev/null
+++ b/core/tests/Drupal/TestTools/HttpKernel/KernelTestHttpKernelBrowser.php
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\TestTools\HttpKernel;
+
+use Symfony\Component\HttpKernel\HttpKernelBrowser;
+
+/**
+ * Browserkit client for use in kernel tests.
+ *
+ * This overrides getAbsoluteUri() to skip the conversion from a relative URI to
+ * an absolute URI. We are using this with the HTTP kernel and that needs a
+ * relative URI.
+ */
+class KernelTestHttpKernelBrowser extends HttpKernelBrowser {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getAbsoluteUri(string $uri): string {
+    // Preserve the given relative URI.
+    return $uri;
+  }
+
+}
-- 
GitLab


From 97da057ea75fb2179827c7ee24c1456ec071a50e Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Fri, 11 Oct 2024 13:17:19 +0100
Subject: [PATCH 03/39] wip KTB.

---
 .../Drupal/KernelTests/KernelTestBase.php     | 110 ++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 0cc4ba3f086a..ef22e2501966 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -5,6 +5,9 @@
 namespace Drupal\KernelTests;
 
 use Behat\Mink\Session;
+use Behat\Mink\Driver\BrowserKitDriver;
+use Behat\Mink\Mink;
+use Behat\Mink\Selector\SelectorsHandler;
 use Drupal\Component\FileCache\ApcuFileCacheBackend;
 use Drupal\Component\FileCache\FileCache;
 use Drupal\Component\FileCache\FileCacheFactory;
@@ -29,6 +32,7 @@
 use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait;
 use Drupal\TestTools\Extension\Dump\DebugDump;
 use Drupal\TestTools\Extension\SchemaInspector;
+use Drupal\TestTools\HttpKernel\KernelTestHttpKernelBrowser;
 use PHPUnit\Framework\Attributes\After;
 use PHPUnit\Framework\Attributes\BeforeClass;
 use PHPUnit\Framework\Exception;
@@ -923,6 +927,112 @@ protected function disableModules(array $modules) {
     }
   }
 
+  /**
+   * Retrieves a Drupal path or an absolute path.
+   *
+   * @todo say this doesn't handle redirects -- in BTB it does.
+   *
+   * @param string|\Drupal\Core\Url $path
+   *   Drupal path or URL to load into Mink controlled browser.
+   * @param array $options
+   *   (optional) Options to be forwarded to the URL generator.
+   * @param string[] $headers
+   *   An array containing additional HTTP request headers, the array keys are
+   *   the header names and the array values the header values. This is useful
+   *   to set for example the "Accept-Language" header for requesting the page
+   *   in a different language. Note that not all headers are supported, for
+   *   example the "Accept" header is always overridden by the browser. For
+   *   testing REST APIs it is recommended to obtain a separate HTTP client
+   *   using getHttpClient() and performing requests that way.
+   *
+   * @see \Drupal\Tests\BrowserTestBase::getHttpClient()
+   */
+  protected function drupalGet($path, array $options = [], array $headers = []) {
+    if (!isset($this->minkSession)) {
+      // Initialise the Mink session if this is the first request.
+      $http_kernel = $this->container->get('http_kernel');
+      $browserkit_client = new KernelTestHttpKernelBrowser($http_kernel);
+      $driver = new BrowserKitDriver($browserkit_client);
+      $session = new Session($driver);
+      $session->start();
+    }
+
+    $session->visit($path);
+
+    // if ($this->htmlOutputEnabled) {
+    //   $html_output = 'GET request to: ' . $url;
+    //   $html_output .= '<hr />' . $content;
+    //   $html_output .= $this->formatHtmlOutputHeaders($response->headers->all());
+    //   $this->htmlOutput($html_output);
+    // }
+  }
+
+  /**
+   * Initializes Mink sessions.
+   */
+  protected function initMink() {
+    $driver = $this->getDefaultDriverInstance();
+
+    // TODO: won't work, there is no guzzle!
+    // if ($driver instanceof BrowserKitDriver) {
+    // this bit not needed
+    //   // Turn off curl timeout. Having a timeout is not a problem in a normal
+    //   // test running, but it is a problem when debugging. Also, disable SSL
+    //   // peer verification so that testing under HTTPS always works.
+    //   /** @var \GuzzleHttp\Client $client */
+    //   $client = $this->container->get('http_client_factory')->fromOptions([
+    //     'timeout' => NULL,
+    //     'verify' => FALSE,
+    //   ]);
+
+    //   // Inject a Guzzle middleware to generate debug output for every request
+    //   // performed in the test.
+    //   $handler_stack = $client->getConfig('handler');
+    //   $handler_stack->push($this->getResponseLogHandler());
+
+    //   $driver->getClient()->setClient($client);
+    // }
+
+    $selectors_handler = new SelectorsHandler([
+      'hidden_field_selector' => new HiddenFieldSelector(),
+    ]);
+    $session = new Session($driver, $selectors_handler);
+    $this->mink = new Mink();
+    $this->mink->registerSession('default', $session);
+    $this->mink->setDefaultSessionName('default');
+    $this->registerSessions();
+
+    $this->initFrontPage();
+
+    // Copies cookies from the current environment, for example, XDEBUG_SESSION
+    // in order to support Xdebug.
+    // @see BrowserTestBase::initFrontPage()
+    $cookies = $this->extractCookiesFromRequest(\Drupal::request());
+    foreach ($cookies as $cookie_name => $values) {
+      foreach ($values as $value) {
+        $session->setCookie($cookie_name, $value);
+      }
+    }
+
+    return $session;
+  }
+
+  /**
+   * Gets an instance of the default Mink driver.
+   *
+   * @return \Behat\Mink\Driver\DriverInterface
+   *   Instance of default Mink driver.
+   *
+   * @throws \InvalidArgumentException
+   *   When provided default Mink driver class can't be instantiated.
+   */
+  protected function getDefaultDriverInstance() {
+    $http_kernel = $this->container->get('http_kernel');
+    $browserkit_client = new KernelTestHttpKernelBrowser($http_kernel);
+    $driver = new BrowserKitDriver($browserkit_client);
+    return $driver;
+  }
+
   /**
    * Renders a render array.
    *
-- 
GitLab


From ce3c95d107b24f0385a464485b322361f2380a56 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Fri, 11 Oct 2024 19:51:14 +0100
Subject: [PATCH 04/39] WIP matching up with BTB

---
 .../Drupal/KernelTests/KernelTestBase.php     | 83 +++++++++++++++----
 1 file changed, 67 insertions(+), 16 deletions(-)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index ef22e2501966..1644f956e27d 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -44,6 +44,8 @@
 use org\bovigo\vfs\vfsStream;
 use org\bovigo\vfs\visitor\vfsStreamPrintVisitor;
 use Drupal\Core\Routing\RouteObjectInterface;
+use Drupal\Tests\HiddenFieldSelector;
+use Drupal\Tests\WebAssert;
 use Symfony\Component\Routing\Route;
 use Symfony\Component\VarDumper\VarDumper;
 
@@ -214,8 +216,18 @@ public function __construct(string $name) {
    */
   protected bool $usesSuperUserAccessPolicy;
 
+  /**
+   * Mink session manager.
+   *
+   * This is lazily initialized by the first call to self::drupalGet().
+   *
+   * @var \Behat\Mink\Mink|null
+   */
+  protected ?Mink $mink;
+
   /**
    * The Mink session.
+   * KILL
    *
    * This is lazily initialised.
    *
@@ -948,14 +960,17 @@ protected function disableModules(array $modules) {
    * @see \Drupal\Tests\BrowserTestBase::getHttpClient()
    */
   protected function drupalGet($path, array $options = [], array $headers = []) {
-    if (!isset($this->minkSession)) {
-      // Initialise the Mink session if this is the first request.
-      $http_kernel = $this->container->get('http_kernel');
-      $browserkit_client = new KernelTestHttpKernelBrowser($http_kernel);
-      $driver = new BrowserKitDriver($browserkit_client);
-      $session = new Session($driver);
-      $session->start();
-    }
+    $session = $this->getSession();
+
+    // // todo convert to using initMink
+    // if (!isset($this->minkSession)) {
+    //   // Initialise the Mink session if this is the first request.
+    //   $http_kernel = $this->container->get('http_kernel');
+    //   $browserkit_client = new KernelTestHttpKernelBrowser($http_kernel);
+    //   $driver = new BrowserKitDriver($browserkit_client);
+    //   $session = new Session($driver);
+    //   $session->start();
+    // }
 
     $session->visit($path);
 
@@ -967,6 +982,26 @@ protected function drupalGet($path, array $options = [], array $headers = []) {
     // }
   }
 
+  /**
+   * Returns Mink session.
+   *
+   * @param string $name
+   *   (optional) Name of the session. Defaults to the active session.
+   *
+   * @return \Behat\Mink\Session
+   *   The active Mink session object.
+   */
+  public function getSession($name = NULL) {
+    // Lazily initialize the Mink session. We do this because unlike Browser
+    // tests where there should definitely be requests made, this is not
+    // necessarily the case with Kernel tests.
+    if (!isset($this->mink)) {
+      $this->initMink();
+    }
+
+    return $this->mink->getSession($name);
+  }
+
   /**
    * Initializes Mink sessions.
    */
@@ -1000,19 +1035,21 @@ protected function initMink() {
     $this->mink = new Mink();
     $this->mink->registerSession('default', $session);
     $this->mink->setDefaultSessionName('default');
-    $this->registerSessions();
+    // Don't need this.
+    // $this->registerSessions();
 
-    $this->initFrontPage();
+    // TODO: do we need this?
+    // $this->initFrontPage();
 
     // Copies cookies from the current environment, for example, XDEBUG_SESSION
     // in order to support Xdebug.
     // @see BrowserTestBase::initFrontPage()
-    $cookies = $this->extractCookiesFromRequest(\Drupal::request());
-    foreach ($cookies as $cookie_name => $values) {
-      foreach ($values as $value) {
-        $session->setCookie($cookie_name, $value);
-      }
-    }
+    // $cookies = $this->extractCookiesFromRequest(\Drupal::request());
+    // foreach ($cookies as $cookie_name => $values) {
+    //   foreach ($values as $value) {
+    //     $session->setCookie($cookie_name, $value);
+    //   }
+    // }
 
     return $session;
   }
@@ -1033,6 +1070,20 @@ protected function getDefaultDriverInstance() {
     return $driver;
   }
 
+  /**
+   * Returns WebAssert object.
+   *
+   * @param string $name
+   *   (optional) Name of the session. Defaults to the active session.
+   *
+   * @return \Drupal\Tests\WebAssert
+   *   A new web-assert option for asserting the presence of elements with.
+   */
+  public function assertSession($name = NULL) {
+    $this->addToAssertionCount(1);
+    return new WebAssert($this->getSession($name));
+  }
+
   /**
    * Renders a render array.
    *
-- 
GitLab


From f6b9e96963b61ea5409450db8a21361e1f6b7a28 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Fri, 11 Oct 2024 22:35:07 +0100
Subject: [PATCH 05/39] add todo

---
 core/tests/Drupal/KernelTests/KernelTestBase.php | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 1644f956e27d..8f586a86400c 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -944,6 +944,8 @@ protected function disableModules(array $modules) {
    *
    * @todo say this doesn't handle redirects -- in BTB it does.
    *
+   * @todo mention how to log in using UserCreationTrait.
+   *
    * @param string|\Drupal\Core\Url $path
    *   Drupal path or URL to load into Mink controlled browser.
    * @param array $options
-- 
GitLab


From 24457dfdb70cf3dd9317852e589021bfac53ecce Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Fri, 11 Oct 2024 22:36:30 +0100
Subject: [PATCH 06/39] added WIP for HTML debug output

---
 core/tests/Drupal/KernelTests/KernelTestBase.php | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 8f586a86400c..c408b356fe28 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -44,6 +44,7 @@
 use org\bovigo\vfs\vfsStream;
 use org\bovigo\vfs\visitor\vfsStreamPrintVisitor;
 use Drupal\Core\Routing\RouteObjectInterface;
+use Drupal\Tests\BrowserHtmlDebugTrait;
 use Drupal\Tests\HiddenFieldSelector;
 use Drupal\Tests\WebAssert;
 use Symfony\Component\Routing\Route;
@@ -111,6 +112,7 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa
   use PhpUnitCompatibilityTrait;
   use ProphecyTrait;
   use ExpectDeprecationTrait;
+  use BrowserHtmlDebugTrait;
 
   /**
    * {@inheritdoc}
@@ -976,10 +978,14 @@ protected function drupalGet($path, array $options = [], array $headers = []) {
 
     $session->visit($path);
 
+    // TODO: This doesn't work yet because $this->siteDirectory is in the VFS
+    // by this point, which means that initBrowserOutputFile() sets up
+    // $this->htmlOutputTestId incorrectly.
     // if ($this->htmlOutputEnabled) {
-    //   $html_output = 'GET request to: ' . $url;
-    //   $html_output .= '<hr />' . $content;
-    //   $html_output .= $this->formatHtmlOutputHeaders($response->headers->all());
+    //   $html_output = 'GET request to: ' . $path;
+    //   $out = $session->getPage()->getContent();
+    //   $html_output .= '<hr />' . $out;
+    //   $html_output .= $this->getHtmlOutputHeaders();
     //   $this->htmlOutput($html_output);
     // }
   }
@@ -999,6 +1005,8 @@ public function getSession($name = NULL) {
     // necessarily the case with Kernel tests.
     if (!isset($this->mink)) {
       $this->initMink();
+      // Set up the browser test output file.
+      $this->initBrowserOutputFile();
     }
 
     return $this->mink->getSession($name);
-- 
GitLab


From 3a6413c017b6070be2319708cd8729608d1e4684 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Fri, 11 Oct 2024 22:37:22 +0100
Subject: [PATCH 07/39] remove earlier attempt code

---
 .../Drupal/KernelTests/KernelTestBase.php     | 20 -------------------
 1 file changed, 20 deletions(-)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index c408b356fe28..0d58775e40da 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -227,16 +227,6 @@ public function __construct(string $name) {
    */
   protected ?Mink $mink;
 
-  /**
-   * The Mink session.
-   * KILL
-   *
-   * This is lazily initialised.
-   *
-   * @var \Behat\Mink\Session|null
-   */
-  protected ?Session $minkSession;
-
   /**
    * Registers the dumper CLI handler when the DebugDump extension is enabled.
    */
@@ -966,16 +956,6 @@ protected function disableModules(array $modules) {
   protected function drupalGet($path, array $options = [], array $headers = []) {
     $session = $this->getSession();
 
-    // // todo convert to using initMink
-    // if (!isset($this->minkSession)) {
-    //   // Initialise the Mink session if this is the first request.
-    //   $http_kernel = $this->container->get('http_kernel');
-    //   $browserkit_client = new KernelTestHttpKernelBrowser($http_kernel);
-    //   $driver = new BrowserKitDriver($browserkit_client);
-    //   $session = new Session($driver);
-    //   $session->start();
-    // }
-
     $session->visit($path);
 
     // TODO: This doesn't work yet because $this->siteDirectory is in the VFS
-- 
GitLab


From 2e2de8fd256974970d10f6d72b66f4e6b82d8adf Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Fri, 11 Oct 2024 22:38:58 +0100
Subject: [PATCH 08/39] Converted NodeLinksTest to a kernel test.

---
 .../tests/src/Functional/NodeLinksTest.php    | 51 ----------
 .../node/tests/src/Kernel/NodeLinksTest.php   | 94 +++++++++++++++++++
 2 files changed, 94 insertions(+), 51 deletions(-)
 delete mode 100644 core/modules/node/tests/src/Functional/NodeLinksTest.php
 create mode 100644 core/modules/node/tests/src/Kernel/NodeLinksTest.php

diff --git a/core/modules/node/tests/src/Functional/NodeLinksTest.php b/core/modules/node/tests/src/Functional/NodeLinksTest.php
deleted file mode 100644
index cb70b80a9cf8..000000000000
--- a/core/modules/node/tests/src/Functional/NodeLinksTest.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\Tests\node\Functional;
-
-use Drupal\node\NodeInterface;
-
-/**
- * Tests the output of node links (read more, add new comment, etc).
- *
- * @group node
- */
-class NodeLinksTest extends NodeTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $modules = ['views'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-  /**
-   * Tests that the links can be hidden in the view display settings.
-   */
-  public function testHideLinks(): void {
-    $node = $this->drupalCreateNode([
-      'type' => 'article',
-      'promote' => NodeInterface::PROMOTED,
-    ]);
-
-    // Links are displayed by default.
-    $this->drupalGet('node');
-    $this->assertSession()->pageTextContains($node->getTitle());
-    $this->assertSession()->linkExists('Read more');
-
-    // Hide links.
-    \Drupal::service('entity_display.repository')
-      ->getViewDisplay('node', 'article', 'teaser')
-      ->removeComponent('links')
-      ->save();
-
-    $this->drupalGet('node');
-    $this->assertSession()->pageTextContains($node->getTitle());
-    $this->assertSession()->linkNotExists('Read more');
-  }
-
-}
diff --git a/core/modules/node/tests/src/Kernel/NodeLinksTest.php b/core/modules/node/tests/src/Kernel/NodeLinksTest.php
new file mode 100644
index 000000000000..0bb3faf6e2b1
--- /dev/null
+++ b/core/modules/node/tests/src/Kernel/NodeLinksTest.php
@@ -0,0 +1,94 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\node\Kernel;
+
+use Drupal\Core\Datetime\Entity\DateFormat;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\node\Entity\NodeType;
+use Drupal\node\NodeInterface;
+use Drupal\Tests\node\Traits\NodeCreationTrait;
+use Drupal\Tests\user\Traits\UserCreationTrait;
+
+/**
+ * Tests the output of node links (read more, add new comment, etc).
+ *
+ * @group node
+ */
+class NodeLinksTest extends KernelTestBase {
+
+  use UserCreationTrait;
+  use NodeCreationTrait;
+
+  /**
+   * The modules to enable.
+   *
+   * @var array
+   */
+  protected static $modules = [
+    'system',
+    'user',
+    'field',
+    'datetime',
+    'filter',
+    'text',
+    'node',
+    'views',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $this->installConfig(['filter']);
+    $this->installConfig(['node']);
+    $this->installEntitySchema('user');
+    $this->installEntitySchema('node');
+
+    $this->setUpCurrentUser(permissions: [
+      'access content',
+    ]);
+
+    DateFormat::create([
+      'id' => 'fallback',
+      'label' => 'Fallback',
+      'pattern' => 'Y-m-d',
+    ])->save();
+
+    $node_type = NodeType::create([
+      'type' => 'article',
+      'name' => 'Article',
+    ]);
+    $node_type->save();
+  }
+
+  /**
+   * Tests that the links can be hidden in the view display settings.
+   */
+  public function testHideLinks(): void {
+    $node = $this->createNode([
+      'type' => 'article',
+      'promote' => NodeInterface::PROMOTED,
+    ]);
+
+    // Links are displayed by default.
+    $this->drupalGet('node');
+    return;
+    $this->assertSession()->pageTextContains($node->getTitle());
+    $this->assertSession()->linkExists('Read more');
+
+    // Hide links.
+    \Drupal::service('entity_display.repository')
+      ->getViewDisplay('node', 'article', 'teaser')
+      ->removeComponent('links')
+      ->save();
+
+    $this->drupalGet('node');
+    $this->assertSession()->pageTextContains($node->getTitle());
+    $this->assertSession()->linkNotExists('Read more');
+  }
+
+}
-- 
GitLab


From 2ee7eac0c6abdb08058cf7227890308c0d39b7ff Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sat, 12 Oct 2024 08:07:08 +0100
Subject: [PATCH 09/39] Converted testTaxonomyTermHierarchyBreadcrumbs() to a
 kernel test.

---
 .../tests/src/Functional/TermIndexTest.php    | 18 ----
 .../tests/src/Kernel/TermHierarchyTest.php    | 82 +++++++++++++++++++
 2 files changed, 82 insertions(+), 18 deletions(-)
 create mode 100644 core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php

diff --git a/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
index e782646e1cd7..fd61ab6b9f6b 100644
--- a/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
+++ b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
@@ -235,22 +235,4 @@ public function testTaxonomyIndex(): void {
     $this->assertEquals(0, $index_count, 'Term 2 is not indexed.');
   }
 
-  /**
-   * Tests that there is a link to the parent term on the child term page.
-   */
-  public function testTaxonomyTermHierarchyBreadcrumbs(): void {
-    // Create two taxonomy terms and set term2 as the parent of term1.
-    $term1 = $this->createTerm($this->vocabulary);
-    $term2 = $this->createTerm($this->vocabulary);
-    $term1->parent = [$term2->id()];
-    $term1->save();
-
-    // Verify that the page breadcrumbs include a link to the parent term.
-    $this->drupalGet('taxonomy/term/' . $term1->id());
-    // Breadcrumbs are not rendered with a language, prevent the term
-    // language from being added to the options.
-    // Check that parent term link is displayed when viewing the node.
-    $this->assertSession()->responseContains(Link::fromTextAndUrl($term2->getName(), $term2->toUrl('canonical', ['language' => NULL]))->toString());
-  }
-
 }
diff --git a/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php b/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php
new file mode 100644
index 000000000000..988041ff64b4
--- /dev/null
+++ b/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php
@@ -0,0 +1,82 @@
+<?php
+
+namespace Drupal\Tests\taxonomy\Kernel;
+
+use Drupal\Core\Link;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\Tests\block\Traits\BlockCreationTrait;
+use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait;
+use Drupal\Tests\user\Traits\UserCreationTrait;
+
+/**
+ * Tests term hierarchy.
+ *
+ * @group taxonomy
+ */
+class TermHierarchyTest extends KernelTestBase {
+
+  use UserCreationTrait;
+  use BlockCreationTrait;
+  use TaxonomyTestTrait;
+
+  /**
+   * The modules to enable.
+   *
+   * @var array
+   */
+  protected static $modules = [
+    'system',
+    'user',
+    'block',
+    'node',
+    'filter',
+    'text',
+    'taxonomy',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+    $this->installConfig(['filter']);
+    $this->installEntitySchema('taxonomy_term');
+    $this->installEntitySchema('user');
+
+    $this->container->get('theme_installer')->install(['stark']);
+    $this->container->get('theme.manager')->setActiveTheme(
+      $this->container->get('theme.initialization')->initTheme('stark')
+    );
+
+    $this->placeBlock('system_breadcrumb_block', [
+      'region' => 'content',
+      'theme' => 'stark',
+    ]);
+
+    $this->setUpCurrentUser(permissions: [
+      'administer taxonomy',
+      'bypass node access',
+    ]);
+  }
+
+  /**
+   * Tests that there is a link to the parent term on the child term page.
+   */
+  public function testTaxonomyTermHierarchyBreadcrumbs(): void {
+    $vocabulary = $this->createVocabulary();
+
+    // Create two taxonomy terms and set term2 as the parent of term1.
+    $term1 = $this->createTerm($vocabulary);
+    $term2 = $this->createTerm($vocabulary);
+    $term1->parent = [$term2->id()];
+    $term1->save();
+
+    // Verify that the page breadcrumbs include a link to the parent term.
+    $this->drupalGet('taxonomy/term/' . $term1->id());
+    // Breadcrumbs are not rendered with a language, prevent the term
+    // language from being added to the options.
+    // Check that parent term link is displayed when viewing the node.
+    $this->assertSession()->responseContains(Link::fromTextAndUrl($term2->getName(), $term2->toUrl('canonical', ['language' => NULL]))->toString());
+  }
+
+}
-- 
GitLab


From 6a69afb7305ddc1a892edf892e928f47ccd9bbb4 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sat, 12 Oct 2024 08:57:55 +0100
Subject: [PATCH 10/39] Fixed HTML debug output.

---
 .../tests/Drupal/KernelTests/KernelTestBase.php | 17 +++++++----------
 .../Drupal/Tests/BrowserHtmlDebugTrait.php      |  2 +-
 2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 0d58775e40da..fdf707fdc884 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -958,16 +958,13 @@ protected function drupalGet($path, array $options = [], array $headers = []) {
 
     $session->visit($path);
 
-    // TODO: This doesn't work yet because $this->siteDirectory is in the VFS
-    // by this point, which means that initBrowserOutputFile() sets up
-    // $this->htmlOutputTestId incorrectly.
-    // if ($this->htmlOutputEnabled) {
-    //   $html_output = 'GET request to: ' . $path;
-    //   $out = $session->getPage()->getContent();
-    //   $html_output .= '<hr />' . $out;
-    //   $html_output .= $this->getHtmlOutputHeaders();
-    //   $this->htmlOutput($html_output);
-    // }
+    if ($this->htmlOutputEnabled) {
+      $html_output = 'GET request to: ' . $path;
+      $out = $session->getPage()->getContent();
+      $html_output .= '<hr />' . $out;
+      $html_output .= $this->getHtmlOutputHeaders();
+      $this->htmlOutput($html_output);
+    }
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
index 95c568afd683..b76b6b1a055c 100644
--- a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
+++ b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
@@ -143,7 +143,7 @@ protected function initBrowserOutputFile() {
         file_put_contents($this->htmlOutputDirectory . '/.htaccess', "<IfModule mod_expires.c>\nExpiresActive Off\n</IfModule>\n");
       }
       $this->htmlOutputCounterStorage = $this->htmlOutputDirectory . '/' . $this->htmlOutputClassName . '.counter';
-      $this->htmlOutputTestId = str_replace('sites/simpletest/', '', $this->siteDirectory);
+      $this->htmlOutputTestId = str_replace(['sites/simpletest/', 'vfs://root/'], '', $this->siteDirectory);
       if (is_file($this->htmlOutputCounterStorage)) {
         $this->htmlOutputCounter = max(1, (int) file_get_contents($this->htmlOutputCounterStorage)) + 1;
       }
-- 
GitLab


From de82733c4b5a60c2b7bb72ce6571e3f8c7173310 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sat, 12 Oct 2024 08:59:49 +0100
Subject: [PATCH 11/39] =?UTF-8?q?Removed=20code=20that=20won=E2=80=99t=20w?=
 =?UTF-8?q?ork=20because=20there=E2=80=99s=20no=20Guzzle.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Drupal/KernelTests/KernelTestBase.php     | 20 -------------------
 1 file changed, 20 deletions(-)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index fdf707fdc884..30742f357558 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -995,26 +995,6 @@ public function getSession($name = NULL) {
   protected function initMink() {
     $driver = $this->getDefaultDriverInstance();
 
-    // TODO: won't work, there is no guzzle!
-    // if ($driver instanceof BrowserKitDriver) {
-    // this bit not needed
-    //   // Turn off curl timeout. Having a timeout is not a problem in a normal
-    //   // test running, but it is a problem when debugging. Also, disable SSL
-    //   // peer verification so that testing under HTTPS always works.
-    //   /** @var \GuzzleHttp\Client $client */
-    //   $client = $this->container->get('http_client_factory')->fromOptions([
-    //     'timeout' => NULL,
-    //     'verify' => FALSE,
-    //   ]);
-
-    //   // Inject a Guzzle middleware to generate debug output for every request
-    //   // performed in the test.
-    //   $handler_stack = $client->getConfig('handler');
-    //   $handler_stack->push($this->getResponseLogHandler());
-
-    //   $driver->getClient()->setClient($client);
-    // }
-
     $selectors_handler = new SelectorsHandler([
       'hidden_field_selector' => new HiddenFieldSelector(),
     ]);
-- 
GitLab


From bec4e5e27753f7ca9708b7dad9c31fd14e7053b4 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sat, 12 Oct 2024 09:00:06 +0100
Subject: [PATCH 12/39] =?UTF-8?q?Removed=20sessions=20and=20cookie=20stuff?=
 =?UTF-8?q?=20from=20initMink().=20We=20don=E2=80=99t=20need=20this=3F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 core/tests/Drupal/KernelTests/KernelTestBase.php | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 30742f357558..461a4b46ac2a 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -1002,21 +1002,6 @@ protected function initMink() {
     $this->mink = new Mink();
     $this->mink->registerSession('default', $session);
     $this->mink->setDefaultSessionName('default');
-    // Don't need this.
-    // $this->registerSessions();
-
-    // TODO: do we need this?
-    // $this->initFrontPage();
-
-    // Copies cookies from the current environment, for example, XDEBUG_SESSION
-    // in order to support Xdebug.
-    // @see BrowserTestBase::initFrontPage()
-    // $cookies = $this->extractCookiesFromRequest(\Drupal::request());
-    // foreach ($cookies as $cookie_name => $values) {
-    //   foreach ($values as $value) {
-    //     $session->setCookie($cookie_name, $value);
-    //   }
-    // }
 
     return $session;
   }
-- 
GitLab


From 8de3ec274a57f02c19a81ff4486e9c35c9ca6b5a Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sat, 12 Oct 2024 09:13:06 +0100
Subject: [PATCH 13/39] docs

---
 core/tests/Drupal/KernelTests/KernelTestBase.php | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 461a4b46ac2a..c3821db3ace6 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -934,9 +934,13 @@ protected function disableModules(array $modules) {
   /**
    * Retrieves a Drupal path or an absolute path.
    *
-   * @todo say this doesn't handle redirects -- in BTB it does.
+   * Requests are sent to the HTTP kernel.
    *
-   * @todo mention how to log in using UserCreationTrait.
+   * There is no logged in user. Use \Drupal\Tests\user\Traits\UserCreationTrait
+   * to set a current user.
+   *
+   * There is no theme. To place blocks, a test must first install a theme and
+   * set it as active.
    *
    * @param string|\Drupal\Core\Url $path
    *   Drupal path or URL to load into Mink controlled browser.
-- 
GitLab


From 8ad66a73d4af60c5b66f4dfe06763856968d5a59 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sat, 12 Oct 2024 10:10:31 +0100
Subject: [PATCH 14/39] Added return types to new methods.

---
 core/tests/Drupal/KernelTests/KernelTestBase.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index c3821db3ace6..df1edd0da38e 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -957,7 +957,7 @@ protected function disableModules(array $modules) {
    *
    * @see \Drupal\Tests\BrowserTestBase::getHttpClient()
    */
-  protected function drupalGet($path, array $options = [], array $headers = []) {
+  protected function drupalGet($path, array $options = [], array $headers = []): void {
     $session = $this->getSession();
 
     $session->visit($path);
@@ -996,7 +996,7 @@ public function getSession($name = NULL) {
   /**
    * Initializes Mink sessions.
    */
-  protected function initMink() {
+  protected function initMink(): void {
     $driver = $this->getDefaultDriverInstance();
 
     $selectors_handler = new SelectorsHandler([
-- 
GitLab


From 4cec07e47f8656503311c839e44db6c2d1d94b9c Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sat, 12 Oct 2024 17:43:31 +0100
Subject: [PATCH 15/39] Removed return from initMink().

---
 core/tests/Drupal/KernelTests/KernelTestBase.php | 2 --
 1 file changed, 2 deletions(-)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index df1edd0da38e..b008d3fec710 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -1006,8 +1006,6 @@ protected function initMink(): void {
     $this->mink = new Mink();
     $this->mink->registerSession('default', $session);
     $this->mink->setDefaultSessionName('default');
-
-    return $session;
   }
 
   /**
-- 
GitLab


From e8bad6c6ac28608631fbfc5915bb2f45951eb663 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sat, 12 Oct 2024 17:43:44 +0100
Subject: [PATCH 16/39] Fixed stray return in test.

---
 core/modules/node/tests/src/Kernel/NodeLinksTest.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/core/modules/node/tests/src/Kernel/NodeLinksTest.php b/core/modules/node/tests/src/Kernel/NodeLinksTest.php
index 0bb3faf6e2b1..f10fe3eb03ca 100644
--- a/core/modules/node/tests/src/Kernel/NodeLinksTest.php
+++ b/core/modules/node/tests/src/Kernel/NodeLinksTest.php
@@ -76,7 +76,6 @@ public function testHideLinks(): void {
 
     // Links are displayed by default.
     $this->drupalGet('node');
-    return;
     $this->assertSession()->pageTextContains($node->getTitle());
     $this->assertSession()->linkExists('Read more');
 
-- 
GitLab


From 1651e66c77ad3140a3c042ef186cb6edc3fe2d3c Mon Sep 17 00:00:00 2001
From: Michael Strelan <mstrelan@gmail.com>
Date: Mon, 14 Oct 2024 08:33:14 +1000
Subject: [PATCH 17/39] Fix phpcs

---
 core/modules/taxonomy/tests/src/Functional/TermIndexTest.php | 1 -
 core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php | 2 ++
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
index fd61ab6b9f6b..a3b207278634 100644
--- a/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
+++ b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
@@ -4,7 +4,6 @@
 
 namespace Drupal\Tests\taxonomy\Functional;
 
-use Drupal\Core\Link;
 use Drupal\Core\Database\Database;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 
diff --git a/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php b/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php
index 988041ff64b4..f46f4de5af04 100644
--- a/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php
+++ b/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php
@@ -1,5 +1,7 @@
 <?php
 
+declare(strict_types=1);
+
 namespace Drupal\Tests\taxonomy\Kernel;
 
 use Drupal\Core\Link;
-- 
GitLab


From 8c6e4433710d4b887c22574d5d67dd2ff862ec63 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Mon, 21 Oct 2024 09:43:48 +0100
Subject: [PATCH 18/39] Fixed error in docs.

---
 core/tests/Drupal/KernelTests/KernelTestBase.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index b008d3fec710..1ec30517112f 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -932,7 +932,7 @@ protected function disableModules(array $modules) {
   }
 
   /**
-   * Retrieves a Drupal path or an absolute path.
+   * Retrieves a Drupal path.
    *
    * Requests are sent to the HTTP kernel.
    *
-- 
GitLab


From 32c6e4b5103237cd8428e697d8ebf55f112e60c5 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Mon, 21 Oct 2024 09:52:00 +0100
Subject: [PATCH 19/39] Moved code for HTTP kernel requests to a trait.

---
 .../node/tests/src/Kernel/NodeLinksTest.php   |   2 +
 .../tests/src/Kernel/TermHierarchyTest.php    |   2 +
 .../Drupal/KernelTests/KernelTestBase.php     | 125 ----------------
 .../Drupal/Tests/HttpKernelUiHelperTrait.php  | 141 ++++++++++++++++++
 4 files changed, 145 insertions(+), 125 deletions(-)
 create mode 100644 core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php

diff --git a/core/modules/node/tests/src/Kernel/NodeLinksTest.php b/core/modules/node/tests/src/Kernel/NodeLinksTest.php
index f10fe3eb03ca..f1ce012d5107 100644
--- a/core/modules/node/tests/src/Kernel/NodeLinksTest.php
+++ b/core/modules/node/tests/src/Kernel/NodeLinksTest.php
@@ -8,6 +8,7 @@
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\node\Entity\NodeType;
 use Drupal\node\NodeInterface;
+use Drupal\Tests\HttpKernelUiHelperTrait;
 use Drupal\Tests\node\Traits\NodeCreationTrait;
 use Drupal\Tests\user\Traits\UserCreationTrait;
 
@@ -18,6 +19,7 @@
  */
 class NodeLinksTest extends KernelTestBase {
 
+  use HttpKernelUiHelperTrait;
   use UserCreationTrait;
   use NodeCreationTrait;
 
diff --git a/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php b/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php
index f46f4de5af04..b047c2f7c20c 100644
--- a/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php
+++ b/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php
@@ -7,6 +7,7 @@
 use Drupal\Core\Link;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\Tests\block\Traits\BlockCreationTrait;
+use Drupal\Tests\HttpKernelUiHelperTrait;
 use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait;
 use Drupal\Tests\user\Traits\UserCreationTrait;
 
@@ -17,6 +18,7 @@
  */
 class TermHierarchyTest extends KernelTestBase {
 
+  use HttpKernelUiHelperTrait;
   use UserCreationTrait;
   use BlockCreationTrait;
   use TaxonomyTestTrait;
diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 1ec30517112f..34aca08f15a9 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -4,10 +4,6 @@
 
 namespace Drupal\KernelTests;
 
-use Behat\Mink\Session;
-use Behat\Mink\Driver\BrowserKitDriver;
-use Behat\Mink\Mink;
-use Behat\Mink\Selector\SelectorsHandler;
 use Drupal\Component\FileCache\ApcuFileCacheBackend;
 use Drupal\Component\FileCache\FileCache;
 use Drupal\Component\FileCache\FileCacheFactory;
@@ -32,7 +28,6 @@
 use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait;
 use Drupal\TestTools\Extension\Dump\DebugDump;
 use Drupal\TestTools\Extension\SchemaInspector;
-use Drupal\TestTools\HttpKernel\KernelTestHttpKernelBrowser;
 use PHPUnit\Framework\Attributes\After;
 use PHPUnit\Framework\Attributes\BeforeClass;
 use PHPUnit\Framework\Exception;
@@ -44,9 +39,6 @@
 use org\bovigo\vfs\vfsStream;
 use org\bovigo\vfs\visitor\vfsStreamPrintVisitor;
 use Drupal\Core\Routing\RouteObjectInterface;
-use Drupal\Tests\BrowserHtmlDebugTrait;
-use Drupal\Tests\HiddenFieldSelector;
-use Drupal\Tests\WebAssert;
 use Symfony\Component\Routing\Route;
 use Symfony\Component\VarDumper\VarDumper;
 
@@ -112,7 +104,6 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa
   use PhpUnitCompatibilityTrait;
   use ProphecyTrait;
   use ExpectDeprecationTrait;
-  use BrowserHtmlDebugTrait;
 
   /**
    * {@inheritdoc}
@@ -218,15 +209,6 @@ public function __construct(string $name) {
    */
   protected bool $usesSuperUserAccessPolicy;
 
-  /**
-   * Mink session manager.
-   *
-   * This is lazily initialized by the first call to self::drupalGet().
-   *
-   * @var \Behat\Mink\Mink|null
-   */
-  protected ?Mink $mink;
-
   /**
    * Registers the dumper CLI handler when the DebugDump extension is enabled.
    */
@@ -931,113 +913,6 @@ protected function disableModules(array $modules) {
     }
   }
 
-  /**
-   * Retrieves a Drupal path.
-   *
-   * Requests are sent to the HTTP kernel.
-   *
-   * There is no logged in user. Use \Drupal\Tests\user\Traits\UserCreationTrait
-   * to set a current user.
-   *
-   * There is no theme. To place blocks, a test must first install a theme and
-   * set it as active.
-   *
-   * @param string|\Drupal\Core\Url $path
-   *   Drupal path or URL to load into Mink controlled browser.
-   * @param array $options
-   *   (optional) Options to be forwarded to the URL generator.
-   * @param string[] $headers
-   *   An array containing additional HTTP request headers, the array keys are
-   *   the header names and the array values the header values. This is useful
-   *   to set for example the "Accept-Language" header for requesting the page
-   *   in a different language. Note that not all headers are supported, for
-   *   example the "Accept" header is always overridden by the browser. For
-   *   testing REST APIs it is recommended to obtain a separate HTTP client
-   *   using getHttpClient() and performing requests that way.
-   *
-   * @see \Drupal\Tests\BrowserTestBase::getHttpClient()
-   */
-  protected function drupalGet($path, array $options = [], array $headers = []): void {
-    $session = $this->getSession();
-
-    $session->visit($path);
-
-    if ($this->htmlOutputEnabled) {
-      $html_output = 'GET request to: ' . $path;
-      $out = $session->getPage()->getContent();
-      $html_output .= '<hr />' . $out;
-      $html_output .= $this->getHtmlOutputHeaders();
-      $this->htmlOutput($html_output);
-    }
-  }
-
-  /**
-   * Returns Mink session.
-   *
-   * @param string $name
-   *   (optional) Name of the session. Defaults to the active session.
-   *
-   * @return \Behat\Mink\Session
-   *   The active Mink session object.
-   */
-  public function getSession($name = NULL) {
-    // Lazily initialize the Mink session. We do this because unlike Browser
-    // tests where there should definitely be requests made, this is not
-    // necessarily the case with Kernel tests.
-    if (!isset($this->mink)) {
-      $this->initMink();
-      // Set up the browser test output file.
-      $this->initBrowserOutputFile();
-    }
-
-    return $this->mink->getSession($name);
-  }
-
-  /**
-   * Initializes Mink sessions.
-   */
-  protected function initMink(): void {
-    $driver = $this->getDefaultDriverInstance();
-
-    $selectors_handler = new SelectorsHandler([
-      'hidden_field_selector' => new HiddenFieldSelector(),
-    ]);
-    $session = new Session($driver, $selectors_handler);
-    $this->mink = new Mink();
-    $this->mink->registerSession('default', $session);
-    $this->mink->setDefaultSessionName('default');
-  }
-
-  /**
-   * Gets an instance of the default Mink driver.
-   *
-   * @return \Behat\Mink\Driver\DriverInterface
-   *   Instance of default Mink driver.
-   *
-   * @throws \InvalidArgumentException
-   *   When provided default Mink driver class can't be instantiated.
-   */
-  protected function getDefaultDriverInstance() {
-    $http_kernel = $this->container->get('http_kernel');
-    $browserkit_client = new KernelTestHttpKernelBrowser($http_kernel);
-    $driver = new BrowserKitDriver($browserkit_client);
-    return $driver;
-  }
-
-  /**
-   * Returns WebAssert object.
-   *
-   * @param string $name
-   *   (optional) Name of the session. Defaults to the active session.
-   *
-   * @return \Drupal\Tests\WebAssert
-   *   A new web-assert option for asserting the presence of elements with.
-   */
-  public function assertSession($name = NULL) {
-    $this->addToAssertionCount(1);
-    return new WebAssert($this->getSession($name));
-  }
-
   /**
    * Renders a render array.
    *
diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
new file mode 100644
index 000000000000..c35c1f92b3d9
--- /dev/null
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -0,0 +1,141 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests;
+
+use Behat\Mink\Driver\BrowserKitDriver;
+use Behat\Mink\Mink;
+use Behat\Mink\Selector\SelectorsHandler;
+use Behat\Mink\Session;
+use Drupal\Tests\BrowserHtmlDebugTrait;
+use Drupal\Tests\HiddenFieldSelector;
+use Drupal\Tests\WebAssert;
+use Drupal\TestTools\HttpKernel\KernelTestHttpKernelBrowser;
+
+/**
+ * Provides UI helper methods using the HTTP kernel to make requests.
+ *
+ * This can be used by Kernel tests.
+ */
+trait HttpKernelUiHelperTrait {
+
+  use BrowserHtmlDebugTrait;
+
+  /**
+   * Mink session manager.
+   *
+   * This is lazily initialized by the first call to self::drupalGet().
+   *
+   * @var \Behat\Mink\Mink|null
+   */
+  protected ?Mink $mink;
+
+  /**
+   * Retrieves a Drupal path.
+   *
+   * Requests are sent to the HTTP kernel.
+   *
+   * There is no logged in user. Use \Drupal\Tests\user\Traits\UserCreationTrait
+   * to set a current user.
+   *
+   * There is no theme. To place blocks, a test must first install a theme and
+   * set it as active.
+   *
+   * @param string|\Drupal\Core\Url $path
+   *   Drupal path or URL to load into Mink controlled browser.
+   * @param array $options
+   *   (optional) Options to be forwarded to the URL generator.
+   * @param string[] $headers
+   *   An array containing additional HTTP request headers, the array keys are
+   *   the header names and the array values the header values. This is useful
+   *   to set for example the "Accept-Language" header for requesting the page
+   *   in a different language. Note that not all headers are supported, for
+   *   example the "Accept" header is always overridden by the browser. For
+   *   testing REST APIs it is recommended to obtain a separate HTTP client
+   *   using getHttpClient() and performing requests that way.
+   *
+   * @see \Drupal\Tests\BrowserTestBase::getHttpClient()
+   */
+  protected function drupalGet($path, array $options = [], array $headers = []): void {
+    $session = $this->getSession();
+
+    $session->visit($path);
+
+    if ($this->htmlOutputEnabled) {
+      $html_output = 'GET request to: ' . $path;
+      $out = $session->getPage()->getContent();
+      $html_output .= '<hr />' . $out;
+      $html_output .= $this->getHtmlOutputHeaders();
+      $this->htmlOutput($html_output);
+    }
+  }
+
+  /**
+   * Returns Mink session.
+   *
+   * @param string $name
+   *   (optional) Name of the session. Defaults to the active session.
+   *
+   * @return \Behat\Mink\Session
+   *   The active Mink session object.
+   */
+  public function getSession($name = NULL) {
+    // Lazily initialize the Mink session. We do this because unlike Browser
+    // tests where there should definitely be requests made, this is not
+    // necessarily the case with Kernel tests.
+    if (!isset($this->mink)) {
+      $this->initMink();
+      // Set up the browser test output file.
+      $this->initBrowserOutputFile();
+    }
+
+    return $this->mink->getSession($name);
+  }
+
+  /**
+   * Initializes Mink sessions.
+   */
+  protected function initMink(): void {
+    $driver = $this->getDefaultDriverInstance();
+
+    $selectors_handler = new SelectorsHandler([
+      'hidden_field_selector' => new HiddenFieldSelector(),
+    ]);
+    $session = new Session($driver, $selectors_handler);
+    $this->mink = new Mink();
+    $this->mink->registerSession('default', $session);
+    $this->mink->setDefaultSessionName('default');
+  }
+
+  /**
+   * Gets an instance of the default Mink driver.
+   *
+   * @return \Behat\Mink\Driver\DriverInterface
+   *   Instance of default Mink driver.
+   *
+   * @throws \InvalidArgumentException
+   *   When provided default Mink driver class can't be instantiated.
+   */
+  protected function getDefaultDriverInstance() {
+    $http_kernel = $this->container->get('http_kernel');
+    $browserkit_client = new KernelTestHttpKernelBrowser($http_kernel);
+    $driver = new BrowserKitDriver($browserkit_client);
+    return $driver;
+  }
+
+  /**
+   * Returns WebAssert object.
+   *
+   * @param string $name
+   *   (optional) Name of the session. Defaults to the active session.
+   *
+   * @return \Drupal\Tests\WebAssert
+   *   A new web-assert option for asserting the presence of elements with.
+   */
+  public function assertSession($name = NULL) {
+    $this->addToAssertionCount(1);
+    return new WebAssert($this->getSession($name));
+  }
+
+}
-- 
GitLab


From e1363d50a7d4058a3238eae2fbdef448f1b0232f Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Tue, 5 Nov 2024 09:55:20 +0000
Subject: [PATCH 20/39] Fixed unneeded use statements.

---
 core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
index c35c1f92b3d9..d0195bc63f92 100644
--- a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -8,9 +8,6 @@
 use Behat\Mink\Mink;
 use Behat\Mink\Selector\SelectorsHandler;
 use Behat\Mink\Session;
-use Drupal\Tests\BrowserHtmlDebugTrait;
-use Drupal\Tests\HiddenFieldSelector;
-use Drupal\Tests\WebAssert;
 use Drupal\TestTools\HttpKernel\KernelTestHttpKernelBrowser;
 
 /**
-- 
GitLab


From 13c7ef0a35e83422e24fada3a3899a0dd491354c Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Fri, 13 Dec 2024 13:12:45 +0000
Subject: [PATCH 21/39] Add return types to minimise the baseline

---
 core/.phpstan-baseline.php                        | 13 +------------
 core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php |  4 ++++
 2 files changed, 5 insertions(+), 12 deletions(-)

diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php
index 0abeb6f41cba..dff06b76d3c4 100644
--- a/core/.phpstan-baseline.php
+++ b/core/.phpstan-baseline.php
@@ -52983,18 +52983,7 @@
 	'path' => __DIR__ . '/tests/Drupal/Tests/BrowserTestBase.php',
 ];
 $ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\Tests\\\\BrowserTestBase\\:\\:htmlOutput\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/Drupal/Tests/BrowserTestBase.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\Tests\\\\BrowserTestBase\\:\\:initBrowserOutputFile\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/Drupal/Tests/BrowserTestBase.php',
-];
-$ignoreErrors[] = [
+	// identifier: missingType.return
 	'message' => '#^Method Drupal\\\\Tests\\\\BrowserTestBase\\:\\:initConfig\\(\\) has no return type specified\\.$#',
 	'identifier' => 'missingType.return',
 	'count' => 1,
diff --git a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
index b76b6b1a055c..62f396a6ebda 100644
--- a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
+++ b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
@@ -105,6 +105,8 @@ protected function getHtmlOutputHeaders() {
    *   current page content is used.
    *
    * @see \Drupal\Tests\Listeners\VerbosePrinter::printResult()
+   *
+   * @return void
    */
   protected function htmlOutput($message = NULL) {
     if (!$this->htmlOutputEnabled) {
@@ -123,6 +125,8 @@ protected function htmlOutput($message = NULL) {
 
   /**
    * Creates the directory to store browser output.
+   *
+   * @return void
    */
   protected function initBrowserOutputFile() {
     $browserOutputFile = getenv('BROWSERTEST_OUTPUT_FILE');
-- 
GitLab


From 221e0236a1ae57eb093c0a5272049a0815a5bf29 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Fri, 13 Dec 2024 18:39:46 +0000
Subject: [PATCH 22/39] Remove unnecessary code

---
 .../KernelTestHttpKernelBrowser.php           | 26 -------------------
 .../Drupal/Tests/HttpKernelUiHelperTrait.php  |  4 +--
 2 files changed, 2 insertions(+), 28 deletions(-)
 delete mode 100644 core/tests/Drupal/TestTools/HttpKernel/KernelTestHttpKernelBrowser.php

diff --git a/core/tests/Drupal/TestTools/HttpKernel/KernelTestHttpKernelBrowser.php b/core/tests/Drupal/TestTools/HttpKernel/KernelTestHttpKernelBrowser.php
deleted file mode 100644
index 37e6eb5aa218..000000000000
--- a/core/tests/Drupal/TestTools/HttpKernel/KernelTestHttpKernelBrowser.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\TestTools\HttpKernel;
-
-use Symfony\Component\HttpKernel\HttpKernelBrowser;
-
-/**
- * Browserkit client for use in kernel tests.
- *
- * This overrides getAbsoluteUri() to skip the conversion from a relative URI to
- * an absolute URI. We are using this with the HTTP kernel and that needs a
- * relative URI.
- */
-class KernelTestHttpKernelBrowser extends HttpKernelBrowser {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getAbsoluteUri(string $uri): string {
-    // Preserve the given relative URI.
-    return $uri;
-  }
-
-}
diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
index d0195bc63f92..06baad3448c0 100644
--- a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -8,7 +8,7 @@
 use Behat\Mink\Mink;
 use Behat\Mink\Selector\SelectorsHandler;
 use Behat\Mink\Session;
-use Drupal\TestTools\HttpKernel\KernelTestHttpKernelBrowser;
+use Symfony\Component\HttpKernel\HttpKernelBrowser;
 
 /**
  * Provides UI helper methods using the HTTP kernel to make requests.
@@ -116,7 +116,7 @@ protected function initMink(): void {
    */
   protected function getDefaultDriverInstance() {
     $http_kernel = $this->container->get('http_kernel');
-    $browserkit_client = new KernelTestHttpKernelBrowser($http_kernel);
+    $browserkit_client = new HttpKernelBrowser($http_kernel);
     $driver = new BrowserKitDriver($browserkit_client);
     return $driver;
   }
-- 
GitLab


From 361e0abc105b0feab703c347cce30ef3b5e9a62d Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sat, 25 Jan 2025 12:41:00 +0000
Subject: [PATCH 23/39] Fixed order of module installation in NodeLinksTest.

---
 core/modules/node/tests/src/Kernel/NodeLinksTest.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/modules/node/tests/src/Kernel/NodeLinksTest.php b/core/modules/node/tests/src/Kernel/NodeLinksTest.php
index f1ce012d5107..a914c871046a 100644
--- a/core/modules/node/tests/src/Kernel/NodeLinksTest.php
+++ b/core/modules/node/tests/src/Kernel/NodeLinksTest.php
@@ -45,10 +45,10 @@ class NodeLinksTest extends KernelTestBase {
   protected function setUp(): void {
     parent::setUp();
 
-    $this->installConfig(['filter']);
-    $this->installConfig(['node']);
     $this->installEntitySchema('user');
     $this->installEntitySchema('node');
+    $this->installConfig(['filter']);
+    $this->installConfig(['node']);
 
     $this->setUpCurrentUser(permissions: [
       'access content',
-- 
GitLab


From 9f931b6d47220efc37ab2088ffdf7397807df7aa Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sun, 26 Jan 2025 20:48:34 +0000
Subject: [PATCH 24/39] Changed drupalGet() to return the HTML.

---
 core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
index 06baad3448c0..3efb8d9dd449 100644
--- a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -52,20 +52,26 @@ trait HttpKernelUiHelperTrait {
    *   testing REST APIs it is recommended to obtain a separate HTTP client
    *   using getHttpClient() and performing requests that way.
    *
+   * @return string
+   *   The retrieved HTML string.
+   *
    * @see \Drupal\Tests\BrowserTestBase::getHttpClient()
    */
-  protected function drupalGet($path, array $options = [], array $headers = []): void {
+  protected function drupalGet($path, array $options = [], array $headers = []): string {
     $session = $this->getSession();
 
     $session->visit($path);
 
+    $out = $session->getPage()->getContent();
+
     if ($this->htmlOutputEnabled) {
       $html_output = 'GET request to: ' . $path;
-      $out = $session->getPage()->getContent();
       $html_output .= '<hr />' . $out;
       $html_output .= $this->getHtmlOutputHeaders();
       $this->htmlOutput($html_output);
     }
+
+    return $out;
   }
 
   /**
-- 
GitLab


From f440cef5aaa439568135312efcd4393f9f5c9e90 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sun, 26 Jan 2025 20:50:17 +0000
Subject: [PATCH 25/39] Fixed wording of docs on lack of a theme.

---
 core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
index 3efb8d9dd449..b047e53d7dfc 100644
--- a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -36,8 +36,8 @@ trait HttpKernelUiHelperTrait {
    * There is no logged in user. Use \Drupal\Tests\user\Traits\UserCreationTrait
    * to set a current user.
    *
-   * There is no theme. To place blocks, a test must first install a theme and
-   * set it as active.
+   * There is no active theme. To place blocks, a test must first install a
+   * theme and then set it as active.
    *
    * @param string|\Drupal\Core\Url $path
    *   Drupal path or URL to load into Mink controlled browser.
-- 
GitLab


From 43ad56907e8d3e72f256c695f82c8358d22d4252 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Sun, 26 Jan 2025 21:09:19 +0000
Subject: [PATCH 26/39] Added docs on page caching not being available.

---
 core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
index b047e53d7dfc..23fec79c4ba6 100644
--- a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -39,6 +39,9 @@ trait HttpKernelUiHelperTrait {
    * There is no active theme. To place blocks, a test must first install a
    * theme and then set it as active.
    *
+   * Page caching modules will not function, because the
+   * CommandLineOrUnsafeMethod caching policy will deny caching.
+   *
    * @param string|\Drupal\Core\Url $path
    *   Drupal path or URL to load into Mink controlled browser.
    * @param array $options
-- 
GitLab


From fba8eeee4179f887a7a61a1e3645fdff9a8d4107 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <20313-joachim@users.noreply.drupalcode.org>
Date: Thu, 30 Jan 2025 16:47:36 +0000
Subject: [PATCH 27/39] Changing to inheritdoc.

---
 core/modules/node/tests/src/Kernel/NodeLinksTest.php | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/core/modules/node/tests/src/Kernel/NodeLinksTest.php b/core/modules/node/tests/src/Kernel/NodeLinksTest.php
index a914c871046a..eaf1de622c1d 100644
--- a/core/modules/node/tests/src/Kernel/NodeLinksTest.php
+++ b/core/modules/node/tests/src/Kernel/NodeLinksTest.php
@@ -24,9 +24,7 @@ class NodeLinksTest extends KernelTestBase {
   use NodeCreationTrait;
 
   /**
-   * The modules to enable.
-   *
-   * @var array
+   * {@inheritdoc}
    */
   protected static $modules = [
     'system',
-- 
GitLab


From 4ab752f51c79e40c7d1ed6a59559a8e145468762 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <20313-joachim@users.noreply.drupalcode.org>
Date: Thu, 30 Jan 2025 16:47:48 +0000
Subject: [PATCH 28/39] Changing to inheritdoc.

---
 core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php b/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php
index b047c2f7c20c..829989e64aa6 100644
--- a/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php
+++ b/core/modules/taxonomy/tests/src/Kernel/TermHierarchyTest.php
@@ -24,9 +24,7 @@ class TermHierarchyTest extends KernelTestBase {
   use TaxonomyTestTrait;
 
   /**
-   * The modules to enable.
-   *
-   * @var array
+   * {@inheritdoc}
    */
   protected static $modules = [
     'system',
-- 
GitLab


From 826108fdf53e4751827d2f8c693d7dd8a8b4d654 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Thu, 30 Jan 2025 16:51:17 +0000
Subject: [PATCH 29/39] Added return types.

---
 core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
index 23fec79c4ba6..a7177b89573a 100644
--- a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -5,9 +5,11 @@
 namespace Drupal\Tests;
 
 use Behat\Mink\Driver\BrowserKitDriver;
+use Behat\Mink\Driver\DriverInterface;
 use Behat\Mink\Mink;
 use Behat\Mink\Selector\SelectorsHandler;
 use Behat\Mink\Session;
+use Drupal\Tests\WebAssert;
 use Symfony\Component\HttpKernel\HttpKernelBrowser;
 
 /**
@@ -86,7 +88,7 @@ protected function drupalGet($path, array $options = [], array $headers = []): s
    * @return \Behat\Mink\Session
    *   The active Mink session object.
    */
-  public function getSession($name = NULL) {
+  public function getSession($name = NULL): Session {
     // Lazily initialize the Mink session. We do this because unlike Browser
     // tests where there should definitely be requests made, this is not
     // necessarily the case with Kernel tests.
@@ -123,7 +125,7 @@ protected function initMink(): void {
    * @throws \InvalidArgumentException
    *   When provided default Mink driver class can't be instantiated.
    */
-  protected function getDefaultDriverInstance() {
+  protected function getDefaultDriverInstance(): DriverInterface {
     $http_kernel = $this->container->get('http_kernel');
     $browserkit_client = new HttpKernelBrowser($http_kernel);
     $driver = new BrowserKitDriver($browserkit_client);
@@ -139,7 +141,7 @@ protected function getDefaultDriverInstance() {
    * @return \Drupal\Tests\WebAssert
    *   A new web-assert option for asserting the presence of elements with.
    */
-  public function assertSession($name = NULL) {
+  public function assertSession($name = NULL): WebAssert {
     $this->addToAssertionCount(1);
     return new WebAssert($this->getSession($name));
   }
-- 
GitLab


From 5efd712813b8abfba077d6d4e7d0eb43f6856940 Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Tue, 4 Feb 2025 12:22:38 +0000
Subject: [PATCH 30/39] Fixed handling of Url $path parameter.

---
 core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
index a7177b89573a..fc690e828fe8 100644
--- a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -9,6 +9,7 @@
 use Behat\Mink\Mink;
 use Behat\Mink\Selector\SelectorsHandler;
 use Behat\Mink\Session;
+use Drupal\Core\Url;
 use Drupal\Tests\WebAssert;
 use Symfony\Component\HttpKernel\HttpKernelBrowser;
 
@@ -63,6 +64,14 @@ trait HttpKernelUiHelperTrait {
    * @see \Drupal\Tests\BrowserTestBase::getHttpClient()
    */
   protected function drupalGet($path, array $options = [], array $headers = []): string {
+    // Convert a Url object to a string.
+    if ($path instanceof Url) {
+      $url_options = $path->getOptions();
+      $options = $url_options + $options;
+      $path->setOptions($options);
+      $path = $path->setAbsolute(FALSE)->toString();
+    }
+
     $session = $this->getSession();
 
     $session->visit($path);
-- 
GitLab


From 822e56af52b9722173f4eacd3a2cccfc55fbd07d Mon Sep 17 00:00:00 2001
From: Joachim Noreiko <joachim@107701.no-reply.drupal.org>
Date: Tue, 4 Feb 2025 12:57:51 +0000
Subject: [PATCH 31/39] Added note about repeated requests.

---
 core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
index fc690e828fe8..c9fe1ac8e4c1 100644
--- a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -45,6 +45,10 @@ trait HttpKernelUiHelperTrait {
    * Page caching modules will not function, because the
    * CommandLineOrUnsafeMethod caching policy will deny caching.
    *
+   * Some requests may not function correctly because DrupalKernel is not
+   * explicitly designed to handle multiple requests: see
+   * https://www.drupal.org/project/drupal/issues/2708827.
+   *
    * @param string|\Drupal\Core\Url $path
    *   Drupal path or URL to load into Mink controlled browser.
    * @param array $options
-- 
GitLab


From 0f9238637d4d7e9f7716cb65ced69183448d39d1 Mon Sep 17 00:00:00 2001
From: Michael Strelan <mstrelan@gmail.com>
Date: Fri, 4 Apr 2025 09:56:23 +1000
Subject: [PATCH 32/39] Set $this->content

---
 core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
index c9fe1ac8e4c1..ab48ef106312 100644
--- a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -81,6 +81,7 @@ protected function drupalGet($path, array $options = [], array $headers = []): s
     $session->visit($path);
 
     $out = $session->getPage()->getContent();
+    $this->content = $out;
 
     if ($this->htmlOutputEnabled) {
       $html_output = 'GET request to: ' . $path;
-- 
GitLab


From 31b7790d37fa716d02c96b9a4226a06f1440e568 Mon Sep 17 00:00:00 2001
From: Michael Strelan <mstrelan@gmail.com>
Date: Thu, 3 Apr 2025 14:38:17 +1000
Subject: [PATCH 33/39] phpcs fixes

---
 core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php   | 4 ++--
 core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php | 1 -
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
index 62f396a6ebda..d71c38caa828 100644
--- a/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
+++ b/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php
@@ -106,7 +106,7 @@ protected function getHtmlOutputHeaders() {
    *
    * @see \Drupal\Tests\Listeners\VerbosePrinter::printResult()
    *
-   * @return void
+   * @phpstan-ignore missingType.return
    */
   protected function htmlOutput($message = NULL) {
     if (!$this->htmlOutputEnabled) {
@@ -126,7 +126,7 @@ protected function htmlOutput($message = NULL) {
   /**
    * Creates the directory to store browser output.
    *
-   * @return void
+   * @phpstan-ignore missingType.return
    */
   protected function initBrowserOutputFile() {
     $browserOutputFile = getenv('BROWSERTEST_OUTPUT_FILE');
diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
index ab48ef106312..840bdbe0194d 100644
--- a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -10,7 +10,6 @@
 use Behat\Mink\Selector\SelectorsHandler;
 use Behat\Mink\Session;
 use Drupal\Core\Url;
-use Drupal\Tests\WebAssert;
 use Symfony\Component\HttpKernel\HttpKernelBrowser;
 
 /**
-- 
GitLab


From 45431198ede13665dd8cabe14297c6ff99b52cb6 Mon Sep 17 00:00:00 2001
From: Michael Strelan <mstrelan@gmail.com>
Date: Fri, 4 Apr 2025 15:09:44 +1000
Subject: [PATCH 34/39] NavigationContentTopTest

---
 .../NavigationContentTopTest.php              | 20 ++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
 rename core/modules/navigation/tests/src/{Functional => Kernel}/NavigationContentTopTest.php (71%)

diff --git a/core/modules/navigation/tests/src/Functional/NavigationContentTopTest.php b/core/modules/navigation/tests/src/Kernel/NavigationContentTopTest.php
similarity index 71%
rename from core/modules/navigation/tests/src/Functional/NavigationContentTopTest.php
rename to core/modules/navigation/tests/src/Kernel/NavigationContentTopTest.php
index 981b628259c7..778261287702 100644
--- a/core/modules/navigation/tests/src/Functional/NavigationContentTopTest.php
+++ b/core/modules/navigation/tests/src/Kernel/NavigationContentTopTest.php
@@ -2,11 +2,13 @@
 
 declare(strict_types=1);
 
-namespace Drupal\Tests\navigation\Functional;
+namespace Drupal\Tests\navigation\Kernel;
 
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Url;
-use Drupal\Tests\BrowserTestBase;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\Tests\HttpKernelUiHelperTrait;
+use Drupal\Tests\user\Traits\UserCreationTrait;
 
 // cspell:ignore foobarbaz baznew
 
@@ -15,17 +17,15 @@
  *
  * @group navigation
  */
-class NavigationContentTopTest extends BrowserTestBase {
+class NavigationContentTopTest extends KernelTestBase {
 
-  /**
-   * {@inheritdoc}
-   */
-  protected static $modules = ['navigation', 'navigation_test', 'test_page_test'];
+  use HttpKernelUiHelperTrait;
+  use UserCreationTrait;
 
   /**
    * {@inheritdoc}
    */
-  protected $defaultTheme = 'stark';
+  protected static $modules = ['navigation', 'navigation_test', 'test_page_test', 'user', 'system', 'layout_builder', 'layout_discovery'];
 
   /**
    * {@inheritdoc}
@@ -33,7 +33,9 @@ class NavigationContentTopTest extends BrowserTestBase {
   protected function setUp(): void {
     parent::setUp();
 
-    $this->drupalLogin($this->createUser([
+    $this->installConfig('navigation');
+    $this->installEntitySchema('user');
+    $this->setCurrentUser($this->createUser([
       'access navigation',
     ]));
   }
-- 
GitLab


From afb42332cea6ec2862001d11809715a9fa39f354 Mon Sep 17 00:00:00 2001
From: Michael Strelan <mstrelan@gmail.com>
Date: Fri, 4 Apr 2025 15:52:13 +1000
Subject: [PATCH 35/39] NavigationDefaultBlockDefinitionTest

---
 .../NavigationDefaultBlockDefinitionTest.php  | 23 ++++++++++++++-----
 1 file changed, 17 insertions(+), 6 deletions(-)
 rename core/modules/navigation/tests/src/{Functional => Kernel}/NavigationDefaultBlockDefinitionTest.php (74%)

diff --git a/core/modules/navigation/tests/src/Functional/NavigationDefaultBlockDefinitionTest.php b/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
similarity index 74%
rename from core/modules/navigation/tests/src/Functional/NavigationDefaultBlockDefinitionTest.php
rename to core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
index 45cd4a2b20db..520656f5680d 100644
--- a/core/modules/navigation/tests/src/Functional/NavigationDefaultBlockDefinitionTest.php
+++ b/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
@@ -5,24 +5,32 @@
 namespace Drupal\Tests\navigation\Functional;
 
 use Drupal\Core\Url;
-use Drupal\Tests\BrowserTestBase;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\Tests\HttpKernelUiHelperTrait;
+use Drupal\Tests\user\Traits\UserCreationTrait;
 
 /**
  * Tests the default block provider logic.
  *
  * @group navigation
  */
-class NavigationDefaultBlockDefinitionTest extends BrowserTestBase {
+class NavigationDefaultBlockDefinitionTest extends KernelTestBase {
+
+  use HttpKernelUiHelperTrait;
+  use UserCreationTrait;
 
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['test_page_test', 'block'];
+  protected static $modules = ['test_page_test', 'block', 'user', 'system', 'layout_discovery', 'layout_builder'];
 
   /**
    * {@inheritdoc}
    */
-  protected $defaultTheme = 'stark';
+  protected function setUp(): void {
+    parent::setUp();
+    $this->installEntitySchema('user');
+  }
 
   /**
    * Tests the default block flow enabling Navigation module first.
@@ -33,13 +41,15 @@ public function testNavigationDefaultAfterNavigation(): void {
 
     // After installing Navigation, the bar is present, but not the block.
     $module_installer->install(['navigation']);
-    $this->drupalLogin($this->drupalCreateUser(['access navigation']));
+    $this->installConfig(['navigation']);
+    $this->setCurrentUser($this->createUser(['access navigation']));
     $this->drupalGet($test_page_url);
     $this->assertSession()->elementExists('css', '.admin-toolbar');
     $this->assertSession()->elementNotExists('css', '.toolbar-button--icon--test-block');
 
     // After installing Navigation Test Block, both elements are present.
     $module_installer->install(['navigation_test_block']);
+    // @todo investigate why lazy builder is not working here.
     $this->drupalGet($test_page_url);
     $this->assertSession()->elementExists('css', '.admin-toolbar');
     $this->assertSession()->elementContains('css', '.toolbar-button--icon--test-block', 'Test Navigation Block');
@@ -60,7 +70,8 @@ public function testNavigationDefaultBeforeNavigation(): void {
 
     // After installing Navigation, both elements are present.
     $module_installer->install(['navigation']);
-    $this->drupalLogin($this->drupalCreateUser(['access navigation']));
+    $this->installConfig(['navigation']);
+    $this->setCurrentUser($this->createUser(['access navigation']));
     $this->drupalGet($test_page_url);
     $this->assertSession()->elementExists('css', '.admin-toolbar');
     $this->assertSession()->elementContains('css', '.toolbar-button--icon--test-block', 'Test Navigation Block');
-- 
GitLab


From 0524c27d56ca0bbe13339d9fbd2b7a772dd2e8da Mon Sep 17 00:00:00 2001
From: Michael Strelan <mstrelan@gmail.com>
Date: Wed, 16 Apr 2025 16:05:22 +1000
Subject: [PATCH 36/39] Fix lazy builder render cache

---
 .../tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php b/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
index 520656f5680d..033a4b8e9d66 100644
--- a/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
+++ b/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
@@ -4,6 +4,7 @@
 
 namespace Drupal\Tests\navigation\Functional;
 
+use Drupal\Core\Test\RefreshVariablesTrait;
 use Drupal\Core\Url;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\Tests\HttpKernelUiHelperTrait;
@@ -18,6 +19,7 @@ class NavigationDefaultBlockDefinitionTest extends KernelTestBase {
 
   use HttpKernelUiHelperTrait;
   use UserCreationTrait;
+  use RefreshVariablesTrait;
 
   /**
    * {@inheritdoc}
@@ -48,8 +50,8 @@ public function testNavigationDefaultAfterNavigation(): void {
     $this->assertSession()->elementNotExists('css', '.toolbar-button--icon--test-block');
 
     // After installing Navigation Test Block, both elements are present.
+    $this->refreshVariables();
     $module_installer->install(['navigation_test_block']);
-    // @todo investigate why lazy builder is not working here.
     $this->drupalGet($test_page_url);
     $this->assertSession()->elementExists('css', '.admin-toolbar');
     $this->assertSession()->elementContains('css', '.toolbar-button--icon--test-block', 'Test Navigation Block');
-- 
GitLab


From 6817731e82ddfd685a60a711306ad56c8e0a6a89 Mon Sep 17 00:00:00 2001
From: Michael Strelan <mstrelan@gmail.com>
Date: Thu, 17 Apr 2025 08:44:36 +1000
Subject: [PATCH 37/39] Fix namespace

---
 .../tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php b/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
index 033a4b8e9d66..e232ce9f0723 100644
--- a/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
+++ b/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
@@ -2,7 +2,7 @@
 
 declare(strict_types=1);
 
-namespace Drupal\Tests\navigation\Functional;
+namespace Drupal\Tests\navigation\Kernel;
 
 use Drupal\Core\Test\RefreshVariablesTrait;
 use Drupal\Core\Url;
-- 
GitLab


From 92b78e05e1bec55696e06cd5ef29fb7f54190007 Mon Sep 17 00:00:00 2001
From: Michael Strelan <mstrelan@gmail.com>
Date: Thu, 17 Apr 2025 08:46:29 +1000
Subject: [PATCH 38/39] Add refreshVariables to HttpKernelUiHelperTrait

---
 core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
index 840bdbe0194d..1b71ce94be3f 100644
--- a/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
+++ b/core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php
@@ -9,6 +9,7 @@
 use Behat\Mink\Mink;
 use Behat\Mink\Selector\SelectorsHandler;
 use Behat\Mink\Session;
+use Drupal\Core\Test\RefreshVariablesTrait;
 use Drupal\Core\Url;
 use Symfony\Component\HttpKernel\HttpKernelBrowser;
 
@@ -20,6 +21,7 @@
 trait HttpKernelUiHelperTrait {
 
   use BrowserHtmlDebugTrait;
+  use RefreshVariablesTrait;
 
   /**
    * Mink session manager.
@@ -82,6 +84,9 @@ protected function drupalGet($path, array $options = [], array $headers = []): s
     $out = $session->getPage()->getContent();
     $this->content = $out;
 
+    // Ensure that any changes to variables in the other thread are picked up.
+    $this->refreshVariables();
+
     if ($this->htmlOutputEnabled) {
       $html_output = 'GET request to: ' . $path;
       $html_output .= '<hr />' . $out;
-- 
GitLab


From 5809cdd2f8dd4eca43f68e7a05e28771ef05756e Mon Sep 17 00:00:00 2001
From: Michael Strelan <mstrelan@gmail.com>
Date: Thu, 17 Apr 2025 08:46:56 +1000
Subject: [PATCH 39/39] Remove refreshVariables from
 NavigationDefaultBlockDefinitionTest

---
 .../tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php  | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php b/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
index e232ce9f0723..e39cb532fa59 100644
--- a/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
+++ b/core/modules/navigation/tests/src/Kernel/NavigationDefaultBlockDefinitionTest.php
@@ -4,7 +4,6 @@
 
 namespace Drupal\Tests\navigation\Kernel;
 
-use Drupal\Core\Test\RefreshVariablesTrait;
 use Drupal\Core\Url;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\Tests\HttpKernelUiHelperTrait;
@@ -19,7 +18,6 @@ class NavigationDefaultBlockDefinitionTest extends KernelTestBase {
 
   use HttpKernelUiHelperTrait;
   use UserCreationTrait;
-  use RefreshVariablesTrait;
 
   /**
    * {@inheritdoc}
@@ -50,7 +48,6 @@ public function testNavigationDefaultAfterNavigation(): void {
     $this->assertSession()->elementNotExists('css', '.toolbar-button--icon--test-block');
 
     // After installing Navigation Test Block, both elements are present.
-    $this->refreshVariables();
     $module_installer->install(['navigation_test_block']);
     $this->drupalGet($test_page_url);
     $this->assertSession()->elementExists('css', '.admin-toolbar');
-- 
GitLab