trait HttpKernelUiHelperTrait

Same name and namespace in other branches
  1. 11.x core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php \Drupal\Tests\HttpKernelUiHelperTrait

Provides UI helper methods using the HTTP kernel to make requests.

This is for use by Kernel tests, with the following limitations:

Hierarchy

4 files declare their use of HttpKernelUiHelperTrait
KernelTestBase.php in core/tests/Drupal/KernelTests/KernelTestBase.php
KernelTestHttpCacheRequestTest.php in core/tests/Drupal/KernelTests/KernelTestHttpCacheRequestTest.php
KernelTestHttpDynamicCacheRequestTest.php in core/tests/Drupal/KernelTests/KernelTestHttpDynamicCacheRequestTest.php
KernelTestHttpRequestTest.php in core/tests/Drupal/KernelTests/KernelTestHttpRequestTest.php

File

core/tests/Drupal/Tests/HttpKernelUiHelperTrait.php, line 28

Namespace

Drupal\Tests
View source
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.
   *
   * @param \Drupal\Core\Url|string $path
   *   The Drupal path to load into Mink controlled browser, as a string or a
   *   Url object. (Note that the Symfony browser's functionality of paths
   *   relative to the previous request is not available, because an initial '/'
   *   is assumed if not present.)
   * @param array $options
   *   (optional) Options to be forwarded to the URL generator. The 'absolute'
   *   option is not supported.
   * @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 Mink's BrowserKitDriver normalizes
   *   header names to uppercase, while Symfony's HTTP classes normalize to
   *   lower case, which may cause a header to not be found with certain APIs.
   *
   * @return string
   *   The retrieved HTML string.
   *
   * @see \Drupal\Tests\BrowserTestBase::getHttpClient()
   */
  protected function drupalGet($path, array $options = [], array $headers = []) : string {
    $session = $this->getSession();
    if (is_string($path) && !str_starts_with($path, '/')) {
      $path = '/' . $path;
    }
    if (is_object($path) || $options) {
      $path = $this->buildUrl($path, $options);
    }
    foreach ($headers as $header_name => $header_value) {
      assert(is_string($header_name));
      $session->setRequestHeader($header_name, $header_value);
    }
    $session->visit($path);
    $out = $session->getPage()
      ->getContent();
    if ($this->htmlOutputEnabled) {
      $html_output = 'GET request to: ' . $path;
      $html_output .= '<hr />' . $out;
      $html_output .= $this->getHtmlOutputHeaders();
      $this->htmlOutput($html_output);
    }
    return $out;
  }
  
  /**
   * Follows a link by complete name.
   *
   * Will click the first link found with this link text unless $index is
   * specified.
   *
   * If the link is not found, an assertion will fail, halting the test.
   *
   * @param string|\Stringable $label
   *   Text between the anchor tags.
   * @param int $index
   *   (optional) The index number for cases where multiple links have the same
   *   text. Defaults to 0.
   */
  protected function clickLink(string|\Stringable $label, int $index = 0) : void {
    $label = (string) $label;
    $links = $this->getSession()
      ->getPage()
      ->findAll('named', [
      'link',
      $label,
    ]);
    $this->assertArrayHasKey($index, $links, 'The link ' . $label . ' was not found on the page.');
    // Use static::drupalGet() rather than the click() method on the element,
    // because that will not produce HTML debug output.
    $this->drupalGet($links[$index]->getAttribute('href'));
  }
  
  /**
   * Builds a URL from a system path or a URL object.
   *
   * @param string|\Drupal\Core\Url $path
   *   A system path or a URL object.
   * @param array $options
   *   Options to be passed to Url::fromUri(). If $path is a Url object, any
   *   options it has will take priority over this parameter.
   *
   * @return string
   *   A URL string.
   */
  protected function buildUrl(Url|string $path, array $options = []) : string {
    assert(empty($options['absolute']), 'Absolute URLs are not usable with drupalGet().');
    if ($path instanceof Url) {
      if ($options) {
        $url_options = $path->getOptions();
        $options = $url_options + $options;
        $path->setOptions($options);
      }
      return $path->toString();
    }
    $uri = $path === '<front>' ? 'base:/' : 'base:/' . $path;
    return Url::fromUri($uri, $options)->toString();
  }
  
  /**
   * Returns Mink session.
   *
   * The lazily initializes Mink the first time it is called.
   *
   * @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) : 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.
    if (!isset($this->mink)) {
      $this->initMink();
      // Set up the browser test output file.
      $this->initBrowserOutputFile();
    }
    return $this->mink
      ->getSession($name);
  }
  
  /**
   * Initializes Mink sessions.
   *
   * Helper for static::getSession().
   */
  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() : DriverInterface {
    $http_kernel = $this->container
      ->get('http_kernel');
    $browserkit_client = new HttpKernelBrowser($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) : WebAssert {
    $this->addToAssertionCount(1);
    return new WebAssert($this->getSession($name));
  }
  
  /**
   * Performs an xpath search on the contents of the internal browser.
   *
   * The search is relative to the root element (HTML tag normally) of the page.
   *
   * This method is identical to \Drupal\Tests\BrowserTestBase::xpath() and
   * should be used when converting Browser tests to Kernel tests, as
   * \Drupal\KernelTests\AssertContentTrait::xpath() which Kernel tests use does
   * not have the same return type.
   *
   * @param string $xpath
   *   The xpath string to use in the search.
   * @param array $arguments
   *   An array of arguments with keys in the form ':name' matching the
   *   placeholders in the query. The values may be either strings or numeric
   *   values.
   *
   * @return \Behat\Mink\Element\NodeElement[]
   *   The list of elements matching the xpath expression.
   */
  protected function getNodeElementsByXpath($xpath, array $arguments = []) : array {
    $xpath = $this->assertSession()
      ->buildXPathQuery($xpath, $arguments);
    return $this->getSession()
      ->getPage()
      ->findAll('xpath', $xpath);
  }
  
  /**
   * Gets the current URL from the browser.
   *
   * @see \Drupal\Tests\UiHelperTrait::getUrl
   */
  protected function getUrl() : string {
    return $this->getSession()
      ->getCurrentUrl();
  }

}

Members

Title Sort descending Modifiers Object type Summary Overrides
BrowserHtmlDebugTrait::$htmlOutputBaseUrl protected property The Base URI to use for links to the output files.
BrowserHtmlDebugTrait::$htmlOutputClassName protected property Class name for HTML output logging.
BrowserHtmlDebugTrait::$htmlOutputCounter protected property Counter for HTML output logging.
BrowserHtmlDebugTrait::$htmlOutputCounterStorage protected property Counter storage for HTML output logging.
BrowserHtmlDebugTrait::$htmlOutputDirectory protected property Directory name for HTML output logging.
BrowserHtmlDebugTrait::$htmlOutputEnabled protected property HTML output enabled.
BrowserHtmlDebugTrait::$htmlOutputTestId protected property HTML output test ID.
BrowserHtmlDebugTrait::formatHtmlOutputHeaders protected function Formats HTTP headers as string for HTML output logging.
BrowserHtmlDebugTrait::getHtmlOutputHeaders protected function Returns headers in HTML output format. 1
BrowserHtmlDebugTrait::getResponseLogHandler protected function Provides a Guzzle middleware handler to log every response received.
BrowserHtmlDebugTrait::getTestMethodCaller protected function Retrieves the current calling line in the class under test. 1
BrowserHtmlDebugTrait::htmlOutput protected function Logs a HTML output message in a text file.
BrowserHtmlDebugTrait::initBrowserOutputFile protected function Creates the directory to store browser output.
HttpKernelUiHelperTrait::$mink protected property Mink session manager.
HttpKernelUiHelperTrait::assertSession public function Returns WebAssert object.
HttpKernelUiHelperTrait::buildUrl protected function Builds a URL from a system path or a URL object.
HttpKernelUiHelperTrait::clickLink protected function Follows a link by complete name.
HttpKernelUiHelperTrait::drupalGet protected function Retrieves a Drupal path.
HttpKernelUiHelperTrait::getDefaultDriverInstance protected function Gets an instance of the default Mink driver.
HttpKernelUiHelperTrait::getNodeElementsByXpath protected function Performs an xpath search on the contents of the internal browser.
HttpKernelUiHelperTrait::getSession public function Returns Mink session.
HttpKernelUiHelperTrait::getUrl protected function Gets the current URL from the browser.
HttpKernelUiHelperTrait::initMink protected function Initializes Mink sessions.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.