Test for number of a items in a list with Behat

By Bill Seremetis, 30 November, 2023

It's common to have list to create navigational pages, links inside blocks. Much like Dublin City Council does for make a list of actions available to its visitors:

Image
Dublin City Council navigation screenshot

These "menus" vary by page, and they are of course dynamic. While doing the Drupal 10 upgrades, Twig and other deprecations affected those pages, by allowing more items to be rendered on each block.

While the fix was easy, it became apparent that we weren't testing for such a scenario in our Behat suite. So I went on and made a new Behat definition that counts how many items are in an HTML list:

 /**
   * @Then /^I should see a list with "([^"]*)" items in block number "([^"]*)" of the grid with selector "([^"]*)"$/
   */
  public function iShouldSeeAListWithItemsInBlockNumberOfTheGridWithSelector(int $arg1, int $arg2, string $arg3) {
    $page = $this->getSession()->getPage();
    $menu = $page->find("css", $arg3 . ' .menu');
    if (null === $menu) {
      throw new \Exception('The grid with selector ' . $arg3 . ' is not found');
    }
    $block = $menu->find("css", "li:nth-child(" . $arg2 . ") ul");
    if (null === $block) {
      throw new \Exception('The block is not found');
    }
    $list = $block->find("css", "ul");
    if (null === $list) {
      throw new \Exception('The list is not found');
    }
    $items = $list->findAll("css", "li");
    if (count($items) !== $arg1) {
      throw new \Exception('The list has a different amount of items');
    }
  

It can be called like this:

Then I should see a list with "5" items in block number "2" of the grid with selector ".business__menu"

It runs much faster than a Visual Regression test and it will not fail if the text of the items/links changes. It will only fail if more or less items are rendered, which in return means that something in the code generating this navigation element has changed drammatically.

Tags