Skip to content

Instantly share code, notes, and snippets.

@kevinquillen
Last active July 22, 2020 18:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kevinquillen/e9cf8336b28e838964fcd596ba5488d0 to your computer and use it in GitHub Desktop.
Save kevinquillen/e9cf8336b28e838964fcd596ba5488d0 to your computer and use it in GitHub Desktop.
A Behat definition that will instruct the client to press a vertical tab, useful for forms leveraging Field Group in Drupal (Shiny admin theme).
/**
* @When I press the :vertical_tab vertical tab
* @param $vertical_tab
*/
public function iPressTheVerticalTab($vertical_tab) {
$this->getSession()->getDriver()->click('//*[contains(@class, "node-form")]/div/div[contains(@class, "vertical-tabs")]/ul/*/a/strong[text()="' . $vertical_tab . '"]');
}
@dpagini
Copy link

dpagini commented May 2, 2017

hey - is this working for you in Drupal 8? I can see the xpath is correct for me, but for some reason this won't solve my behat/vertical-tabs problem with PhantomJS.

@shwetaneelsharma
Copy link

Yes, this does work when the script is executed in a physical browser. However, unable to get it working on headless Chrome.

@paulsheldrake
Copy link

The xpath wasn't working for me so I needed to tweak it a bit. This works in @javascript. Gets takes the tab name and then scrolls the tab into view to make sure it's clickable

/**
   * @When I press the :vertical_tab vertical tab
   *
   * @param $vertical_tab
   */
  public function iPressTheVerticalTab($tab_name) {
    $page = $this->getSession()->getPage();
    $vert_tabs_selector = '.vertical-tabs-list';
    $vertical_tabs = $page->find('css', $vert_tabs_selector);
    $this->scrollIntoView($vert_tabs_selector);

    $vertical_tabs_element = $vertical_tabs->find('named', array('content', $tab_name));
    if (empty($vertical_tabs_element)) {
      throw new Exception("No tab found for the selector ('$tab_name')");
    }

    $vertical_tabs_element->click();
  }
  

  /**
   * @When I scroll :selector into view
   *
   * @param string $selector Allowed selectors: #id, .className, //xpath
   * @throws \Exception
   */
  public function scrollIntoView($selector)
  {
    $locator = substr($selector, 0, 1);

    switch ($locator) {
      case '$' : // Query selector
        $selector = substr($selector, 1);
        $function = <<<JS
(function(){
  var elem = document.querySelector("$selector");
  elem.scrollIntoView(false);
})()
JS;
        break;

      case '/' : // XPath selector
        $function = <<<JS
(function(){
  var elem = document.evaluate("$selector", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  elem.scrollIntoView(false);
})()
JS;
        break;

      case '#' : // ID selector
        $selector = substr($selector, 1);
        $function = <<<JS
(function(){
  var elem = document.getElementById("$selector");
  elem.scrollIntoView(false);
})()
JS;
        break;

      case '.' : // Class selector
        $selector = substr($selector, 1);
        $function = <<<JS
(function(){
  var elem = document.getElementsByClassName("$selector");
  elem[0].scrollIntoView(false);
})()
JS;
        break;

      default:
        throw new \Exception(__METHOD__ . ' Couldn\'t find selector: ' . $selector . ' - Allowed selectors: #id, .className, //xpath');
        break;
    }

    try {
      $this->getSession()->executeScript($function);
    } catch (Exception $e) {
      throw new \Exception(__METHOD__ . ' failed');
    }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment