Joeri Timmermans
Joeri Timmermans
PHP/Symfony Developer with
a passion for food and drinks
Developer @ Intracto

How to make smart timeouts for behat events

Monday July 31, 2017 - Permalink - Tags: symfony2, testing, vagrant, selenium, php, behat

Let me start by giving you some background for this problem. We have a lot of popups and other events happening on our frontend and we used timeouts to cover them. But they were always "guessing". Sometimes waiting 3 seconds was enough, but sometimes 5 wasn't enough. Depending on how slow your machine was.

So what we needed to do is create a smart timeout, one that would check if an element was ready, and if not wait a little longer with a maximum timeout. Here is how we did it.

Assumptions

  • You know how to work with Behat (More info)

STEP 1: Create a custom context

In order to create a timeout we need a loop. Here is the function that we used for our element search:

/**
 * Wait for a element.
 *
 * @When (I )wait :count second(s) until I see :element element
 */
public function iWaitSecondsForElement($seconds, $element)
{
    $i = 0;
    while ($i < $seconds) {
        try {
            $this->minkContext->assertElementOnPage($element);
            return;
        } catch (ElementNotFoundException $e) {
            ++$i;
            sleep(1);
        }
    }
    $message = "The element '$element' was not found after a $seconds seconds timeout";
    throw new ResponseTextException($message, $this->getSession());
}

STEP 2: Profit

For the complete class, with all our extra functions and default timeout you can take a look at my gist

Example:

@guided-tour
Feature: Check if the guided tour steps are working correctly.

  Scenario: Start guided tour
    Given I am logged in with user "user@example.com" and password "test"
    When I follow "Guided tour"
    When I wait until I see "Here you can filter between organisations."
    When I follow "next"
    When I wait until I see "This right here is your demo course"
    When I follow "next"
    When I wait until I see "These are your course modules"
comments powered by Disqus