How to use a Select2 input with Behat

This article was published more than 6 months ago, this means the content may be out of date or no longer relevant.

If you are a PHP developer, you might know Behat, the most popuplar Behavior Driven Development (BDD) framework for PHP. Personnaly, I frequently annoyed when I have to write scenario with an UI which is using Select2, because it's not possilbe to manipulate the field natively with Behat and the Mink extension.

To do this work, you need to create a new Behat context where you will add custom actions needed to control the Select2 list. Given there is a very few explanations on the subject, I decide to share the code to do that.

/**
 * @When /^(?:|I )fill in select2 input "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)" and select "(?P<entry>(?:[^"]|\\")*)"$/
 */
public function fillInSelectInputWithAndSelect($field, $value, $entry)
{
    $page = $this->getSession()->getPage();

    $inputField = $page->find('css', $field);
    if (!$inputField) {
        throw new \Exception('No field found');
    }

    $choice = $inputField->getParent()->find('css', '.select2-selection');
    if (!$choice) {
        throw new \Exception('No select2 choice found');
    }
    $choice->press();

    $select2Input = $page->find('css', '.select2-search__field');
    if (!$select2Input) {
        throw new \Exception('No input found');
    }
    $select2Input->setValue($value);

    $this->getSession()->wait(1000);

    $chosenResults = $page->findAll('css', '.select2-results li');
    foreach ($chosenResults as $result) {
        if ($result->getText() == $entry) {
            $result->click();
            break;
        }
    }
}

If you are interested by manipulating a Select2 with Behat, please consider this Behat extension created and open sourced by my current company. It's can be used with Composer and provide the most common feature for Select2. It's also available on Github.