You are here

final class ElementContext in Lightning Core 8.3

Same name and namespace in other branches
  1. 8.5 tests/contexts/ElementContext.behat.inc \Acquia\LightningExtension\Context\ElementContext
  2. 8 tests/contexts/ElementContext.behat.inc \Acquia\LightningExtension\Context\ElementContext
  3. 8.2 tests/contexts/ElementContext.behat.inc \Acquia\LightningExtension\Context\ElementContext
  4. 8.4 tests/contexts/ElementContext.behat.inc \Acquia\LightningExtension\Context\ElementContext

Contains miscellaneous step definitions for working with HTML elements.

@internal This is an internal part of Lightning Core's testing system and may be changed or removed at any time without warning. It should not be extended, instantiated, or used in any way by external code! If you need to use this functionality, you should copy the relevant code into your own project.

Hierarchy

  • class \Acquia\LightningExtension\Context\ElementContext extends \Drupal\DrupalExtension\Context\DrupalSubContextBase

Expanded class hierarchy of ElementContext

File

tests/contexts/ElementContext.behat.inc, line 21

Namespace

Acquia\LightningExtension\Context
View source
final class ElementContext extends DrupalSubContextBase {

  /**
   * Asserts that an element is empty.
   *
   * @param string $selector
   *   The element's CSS selector.
   *
   * @throws \Behat\Mink\Exception\ExpectationException
   *   If the element contains any HTML (leading and trailing white space is
   *   trimmed out).
   *
   * @Then the :selector element(s) should be empty
   */
  public function assertEmptyElement($selector) {
    $content = $this
      ->assertSession()
      ->elementExists('css', $selector)
      ->getHtml();
    if (trim($content)) {
      throw new ExpectationException("Expected element '{$selector}' to be empty, but it is not.", $this
        ->getSession()
        ->getDriver());
    }
  }

  /**
   * Clears a field.
   *
   * @param string $field
   *   The field to clear.
   * @param \Behat\Mink\Element\ElementInterface $container
   *   (optional) The element that contains the field.
   *
   * @When I clear :field
   */
  public function clearField($field, ElementInterface $container = NULL) {
    $this
      ->assertSession()
      ->fieldExists($field, $container)
      ->setValue(FALSE);
  }

  /**
   * Asserts that a form field is present.
   *
   * Oddly, MinkContext does not appear to provide a step definition for this.
   *
   * @param string $field
   *   The field locator.
   *
   * @return \Behat\Mink\Element\NodeElement
   *   The form field element.
   *
   * @Then I should see a(n) :field field
   */
  public function assertField($field) {
    return $this
      ->assertSession()
      ->fieldExists($field);
  }

  /**
   * Asserts that a field element exists and is disabled.
   *
   * @param string $field
   *   The field locator.
   *
   * @return \Behat\Mink\Element\NodeElement
   *   The disabled form field element.
   *
   * @Then I should see a disabled :field field
   * @Then the :field field should be disabled
   */
  public function assertDisabledField($field) {
    return $this
      ->assertSession()
      ->elementAttributeExists('named', [
      'field',
      $field,
    ], 'disabled');
  }

  /**
   * Asserts that a form field is not present.
   *
   * Oddly, MinkContext does not appear to provide a step definition for this.
   *
   * @param string $field
   *   The field locator.
   *
   * @Then I should not see a(n) :field field
   */
  public function assertNoField($field) {
    $this
      ->assertSession()
      ->fieldNotExists($field);
  }

  /**
   * Asserts that a select list has a particular option.
   *
   * @param string $select
   *   The select list to check.
   * @param string $option
   *   The option to look for.
   *
   * @Then the :select field should have a(n) :option option
   */
  public function assertOption($select, $option) {
    $this
      ->assertSession()
      ->elementExists('named', [
      'option',
      $option,
    ], $this
      ->assertField($select));
  }

  /**
   * Asserts that a select list does not have a particular option.
   *
   * @param string $select
   *   The select list to check.
   * @param string $option
   *   The option to look for.
   *
   * @Then the :select field should not have a(n) :option option
   */
  public function assertNoOption($select, $option) {
    $this
      ->assertSession()
      ->elementNotExists('named', [
      'option',
      $option,
    ], $this
      ->assertField($select));
  }

  /**
   * Asserts that a select list has a set of options.
   *
   * @param string $select
   *   The select list to check.
   * @param \Behat\Gherkin\Node\PyStringNode $options
   *   The options to look for.
   *
   * @Then the :select field should have options:
   */
  public function assertOptions($select, PyStringNode $options) {
    foreach ($options
      ->getStrings() as $option) {
      $this
        ->assertOption($select, $option);
    }
  }

  /**
   * Asserts that a select list does not have a set of options.
   *
   * @param string $select
   *   The select list to check.
   * @param \Behat\Gherkin\Node\PyStringNode $options
   *   The options to look for.
   *
   * @Then the :select field should not have options:
   */
  public function assertNoOptions($select, PyStringNode $options) {
    foreach ($options
      ->getStrings() as $option) {
      $this
        ->assertNoOption($select, $option);
    }
  }

  /**
   * Switches to a frame.
   *
   * @param string $name
   *   The frame name.
   *
   * @When I switch to the :name frame
   * @When I enter the :name frame
   */
  public function enterFrame($name) {
    $this
      ->getSession()
      ->switchToIFrame($name);
  }

  /**
   * Switches out of an frame, into the main window.
   *
   * @When I (switch|return) to the window
   * @When I (exit|leave) the frame
   */
  public function exitFrame() {
    $this
      ->getSession()
      ->switchToWindow();
  }

  /**
   * Asserts that vertical tab set exists.
   *
   * @param \Behat\Mink\Element\ElementInterface $container
   *   (optional) The element containing the vertical tab set.
   *
   * @return \Behat\Mink\Element\NodeElement
   *   The vertical tab set.
   *
   * @Then I should see a set of vertical tabs
   */
  public function assertVerticalTabs(ElementInterface $container = NULL) {
    return $this
      ->assertSession()
      ->elementExists('css', 'ul.vertical-tabs__menu', $container);
  }

  /**
   * Asserts that a specific vertical tab exists.
   *
   * @param string $tab
   *   The text of the tab.
   * @param \Behat\Mink\Element\ElementInterface $container
   *   (optional) The element containing the vertical tab set.
   *
   * @return \Behat\Mink\Element\NodeElement
   *   The vertical tab.
   *
   * @Then I should see a :tab vertical tab
   * @Then I should see the :tab vertical tab
   */
  public function assertVerticalTab($tab, ElementInterface $container = NULL) {
    return $this
      ->assertSession()
      ->elementExists('named', [
      'link',
      $tab,
    ], $this
      ->assertVerticalTabs($container));
  }

  /**
   * Asserts that a specific vertical tab does not exist.
   *
   * @param string $tab
   *   The text of the tab.
   * @param \Behat\Mink\Element\ElementInterface $container
   *   (optional) The element containing the vertical tab set.
   *
   * @Then I should not see a :tab vertical tab
   * @Then I should not see the :tab vertical tab
   */
  public function assertNoVerticalTab($tab, ElementInterface $container = NULL) {
    $this
      ->assertSession()
      ->elementNotExists('named', [
      'link',
      $tab,
    ], $this
      ->assertVerticalTabs($container));
  }

  /**
   * Asserts that a specific set of vertical tabs exists.
   *
   * @param \Behat\Gherkin\Node\PyStringNode $tabs
   *   The text of the tabs, one per line.
   * @param \Behat\Mink\Element\ElementInterface $container
   *   (optional) The element containing the vertical tab set.
   *
   * @Then I should see (the )vertical tabs:
   */
  public function assertVerticalTabMultiple(PyStringNode $tabs, ElementInterface $container = NULL) {
    foreach ($tabs
      ->getStrings() as $tab) {
      $this
        ->assertVerticalTab($tab, $container);
    }
  }

  /**
   * Asserts that a set of specific vertical tabs exists.
   *
   * @param \Behat\Gherkin\Node\PyStringNode $tabs
   *   The text of the tabs, one per line.
   * @param \Behat\Mink\Element\ElementInterface $container
   *   (optional) The element containing the vertical tab set.
   *
   * @Then I should not see (the )vertical tabs:
   */
  public function assertNotVerticalTabMultiple(PyStringNode $tabs, ElementInterface $container = NULL) {
    foreach ($tabs
      ->getStrings() as $tab) {
      $this
        ->assertNoVerticalTab($tab, $container);
    }
  }

  /**
   * Asserts the existence of a <details> element by its summary text.
   *
   * @param string $summary
   *   The summary text (case-insensitive).
   * @param \Behat\Mink\Element\ElementInterface $container
   *   The element in which to search for the <details> element.
   *
   * @return \Behat\Mink\Element\NodeElement|bool
   *   The <details> element, or FALSE if it was not found.
   */
  private function findDetails($summary, ElementInterface $container) {
    $lowercase_summary = mb_strtolower($summary);

    /** @var \Behat\Mink\Element\NodeElement $element */
    foreach ($container
      ->findAll('css', 'details > summary') as $element) {
      $lowercase_element_text = mb_strtolower($element
        ->getText());
      if ($lowercase_element_text === $lowercase_summary) {
        return $element
          ->getParent();
      }
    }
    return FALSE;
  }

  /**
   * Asserts the existence of a <details> element by its summary text.
   *
   * @param string $summary
   *   The exact summary text.
   * @param \Behat\Mink\Element\ElementInterface $container
   *   (optional) The element in which to search for the <details> element.
   *
   * @return \Behat\Mink\Element\NodeElement
   *   The <details> element.
   *
   * @throws \Behat\Mink\Exception\ElementNotFoundException
   *   If the element is not found in the container.
   *
   * @Then I should see a(n) :summary details element
   */
  public function assertDetails($summary, ElementInterface $container = NULL) {
    $session = $this
      ->getSession();
    $element = $this
      ->findDetails($summary, $container ?: $session
      ->getPage());
    if ($element) {
      return $element;
    }
    else {
      throw new ElementNotFoundException($session
        ->getDriver(), 'details', 'summary', $summary);
    }
  }

  /**
   * Asserts the existence of an open <details> element by its summary text.
   *
   * @param string $summary
   *   The exact summary text.
   * @param \Behat\Mink\Element\ElementInterface $container
   *   (optional) The element in which to search for the <details> element.
   *
   * @throws \Behat\Mink\Exception\ExpectationException
   *   If the <details> element is closed.
   *
   * @Then I should see an open :summary details element
   */
  public function assertOpenDetails($summary, ElementInterface $container = NULL) {
    $open = $this
      ->assertDetails($summary, $container)
      ->hasAttribute('open');
    if (!$open) {
      throw new ExpectationException("Expected '{$summary}' details to be open, but it is closed.", $this
        ->getSession()
        ->getDriver());
    }
  }

  /**
   * Asserts the existence of a closed <details> element by its summary text.
   *
   * @param string $summary
   *   The exact summary text.
   * @param \Behat\Mink\Element\ElementInterface $container
   *   (optional) The element in which to search for the <details> element.
   *
   * @throws \Behat\Mink\Exception\ExpectationException
   *   If the <details> element is open.
   *
   * @Then I should see a closed :summary details element
   */
  public function assertClosedDetails($summary, ElementInterface $container = NULL) {
    try {
      $this
        ->assertOpenDetails($summary, $container);
    } catch (ExpectationException $e) {
      return;
    }
    throw new ExpectationException("Expected '{$summary}' details to be closed, but it is open.", $this
      ->getSession()
      ->getDriver());
  }

  /**
   * Clicks an arbitrary element, found by CSS selector.
   *
   * @param string $selector
   *   The CSS selector.
   *
   * @When I click the :selector element
   */
  public function click($selector) {
    $element = $this
      ->assertSession()
      ->elementExists('css', $selector);
    try {
      $this
        ->scrollTo($selector);
    } catch (UnsupportedDriverActionException $e) {

      // Don't worry about it.
    }
    $element
      ->click();
  }

  /**
   * Scrolls an element into the viewport.
   *
   * @param string $selector
   *   The element's CSS selector.
   *
   * @When I scroll to the :selector element
   */
  public function scrollTo($selector) {
    $this
      ->getSession()
      ->executeScript('document.querySelector("' . addslashes($selector) . '").scrollIntoView()');
  }

  /**
   * Asserts that a minimum number of elements match a CSS selector.
   *
   * @param string $selector
   *   The selector.
   * @param int $n
   *   The number of elements expected to match the selector.
   *
   * @throws \Behat\Mink\Exception\ExpectationException
   *   If the fewer elements than expected match the selector.
   *
   * @Then at least :n element(s) should match :selector
   */
  public function matchAtLeast($selector, $n) {
    $session = $this
      ->getSession();
    $count = count($session
      ->getPage()
      ->findAll('css', $selector));
    if ($count < $n) {
      throw new ExpectationException("Expected '{$selector}' to match at least {$n} elements, but it matched {$count}.", $session
        ->getDriver());
    }
  }

  /**
   * Asserts that a number of elements match a CSS selector.
   *
   * @param string $selector
   *   The selector.
   * @param int $n
   *   The number of elements expected to match the selector.
   *
   * @Then exactly :n element(s) should match :selector
   */
  public function matchExactly($selector, $n) {
    $this
      ->assertSession()
      ->elementsCount('css', $selector, $n);
  }

  /**
   * Asserts that a block with a specific plugin ID is present.
   *
   * @param string $plugin_id
   *   The block plugin ID.
   *
   * @return \Behat\Mink\Element\ElementInterface
   *   The block element.
   *
   * @Then I should see a :plugin_id block
   */
  public function assertBlockExists($plugin_id) {
    return $this
      ->assertSession()
      ->elementExists('css', "[data-block-plugin-id='{$plugin_id}']");
  }

  /**
   * Asserts that a block with a specific plugin ID is not present.
   *
   * @param string $plugin_id
   *   The block plugin ID.
   *
   * @Then I should not see a :plugin_id block
   */
  public function assertBlockNotExists($plugin_id) {
    $this
      ->assertSession()
      ->elementNotExists('css', "[data-block-plugin-id='{$plugin_id}']");
  }

  /**
   * Asserts that an element has contextual links.
   *
   * @param \Behat\Mink\Element\ElementInterface $element
   *   The element which is expected to contain contextual links.
   *
   * @return \Behat\Mink\Element\ElementInterface
   *   The list of contextual links.
   */
  private function assertContextualLinks(ElementInterface $element) {
    return $this
      ->assertSession()
      ->elementExists('css', 'ul.contextual-links', $element);
  }

  /**
   * Asserts that an element has a specific contextual link.
   *
   * @param \Behat\Mink\Element\ElementInterface $element
   *   The element which is expectd to contain the contextual link.
   * @param string $link_class
   *   The CSS class of the contextual link.
   *
   * @return \Behat\Mink\Element\ElementInterface
   *   The contextual link.
   */
  private function assertContextualLink(ElementInterface $element, $link_class) {
    return $this
      ->assertSession()
      ->elementExists('css', "li.{$link_class}", $this
      ->assertContextualLinks($element));
  }

  /**
   * Asserts that a block has contextual link(s).
   *
   * @param string $plugin_id
   *   The block plugin ID.
   * @param string $link_class
   *   (optional) The CSS class of a specific contextual link.
   *
   * @see ::assertContextualLinks()
   * @see ::assertContextualLink()
   * @see ::assertBlockExists()
   *
   * @Then the :plugin_id block should have contextual links
   * @Then the :plugin_id block should have a :link_class contextual link
   * @Then I should see a :plugin_id block with contextual links
   * @Then I should see a :plugin_id block with a :link_class contextual link
   */
  public function assertBlockHasContextual($plugin_id, $link_class = NULL) {
    $element = $this
      ->assertBlockExists($plugin_id);
    return $link_class ? $this
      ->assertContextualLink($element, $link_class) : $this
      ->assertContextualLinks($element);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ElementContext::assertBlockExists public function Asserts that a block with a specific plugin ID is present.
ElementContext::assertBlockHasContextual public function Asserts that a block has contextual link(s).
ElementContext::assertBlockNotExists public function Asserts that a block with a specific plugin ID is not present.
ElementContext::assertClosedDetails public function Asserts the existence of a closed <details> element by its summary text.
ElementContext::assertContextualLink private function Asserts that an element has a specific contextual link.
ElementContext::assertContextualLinks private function Asserts that an element has contextual links.
ElementContext::assertDetails public function Asserts the existence of a <details> element by its summary text.
ElementContext::assertDisabledField public function Asserts that a field element exists and is disabled.
ElementContext::assertEmptyElement public function Asserts that an element is empty.
ElementContext::assertField public function Asserts that a form field is present.
ElementContext::assertNoField public function Asserts that a form field is not present.
ElementContext::assertNoOption public function Asserts that a select list does not have a particular option.
ElementContext::assertNoOptions public function Asserts that a select list does not have a set of options.
ElementContext::assertNotVerticalTabMultiple public function Asserts that a set of specific vertical tabs exists.
ElementContext::assertNoVerticalTab public function Asserts that a specific vertical tab does not exist.
ElementContext::assertOpenDetails public function Asserts the existence of an open <details> element by its summary text.
ElementContext::assertOption public function Asserts that a select list has a particular option.
ElementContext::assertOptions public function Asserts that a select list has a set of options.
ElementContext::assertVerticalTab public function Asserts that a specific vertical tab exists.
ElementContext::assertVerticalTabMultiple public function Asserts that a specific set of vertical tabs exists.
ElementContext::assertVerticalTabs public function Asserts that vertical tab set exists.
ElementContext::clearField public function Clears a field.
ElementContext::click public function Clicks an arbitrary element, found by CSS selector.
ElementContext::enterFrame public function Switches to a frame.
ElementContext::exitFrame public function Switches out of an frame, into the main window.
ElementContext::findDetails private function Asserts the existence of a <details> element by its summary text.
ElementContext::matchAtLeast public function Asserts that a minimum number of elements match a CSS selector.
ElementContext::matchExactly public function Asserts that a number of elements match a CSS selector.
ElementContext::scrollTo public function Scrolls an element into the viewport.