Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save swichers/f6acf3892493f072f8b1e514de591370 to your computer and use it in GitHub Desktop.
Save swichers/f6acf3892493f072f8b1e514de591370 to your computer and use it in GitHub Desktop.
Behat Step to select an autocomplete suggestion from a partial entry
<?php
use Behat\Mink\Extension\ElementNotFoundException;
use Drupal\DrupalExtension\Context\DrupalContext;
class FeatureContext extends DrupalContext {
/**
* Gives us acess to the other contexts so we can access their properties.
*
* @BeforeScenario
*/
public function gatherContexts(BeforeScenarioScope $scope) {
$environment = $scope->getEnvironment();
$this->contexts['drupal'] = $environment->getContext('Drupal\DrupalExtension\Context\DrupalContext');
$this->contexts['mink'] = $environment->getContext('Drupal\DrupalExtension\Context\MinkContext');
}
/**
* @When I fill in the autocomplete :autocomplete with :text and click :popup
*/
public function fillInDrupalAutocomplete($field, $text, $popup) {
$session = $this->getSession();
$element = $session->getPage()->findField($field);
if (empty($element)) {
throw new ElementNotFoundException($session, NULL, 'named', $field);
}
$element->setValue($text);
$element->focus();
$xpath = $element->getXpath();
$driver = $session->getDriver();
// autocomplete.js uses key down/up events directly.
// Press the down arrow to open the autocomplete options.
$driver->keyDown($xpath, 40);
$driver->keyUp($xpath, 40);
$this->contexts['mink']->iWaitForAjaxToFinish();
$available_autocompletes = $this->getSession()->getPage()->findAll('css', 'ul.ui-autocomplete[id^=ui-id]');
if (empty($available_autocompletes)) {
throw new \Exception(t('Could not find the autocomplete popup box'));
}
// It's possible for multiple autocompletes to be on the page at once,
// but it shouldn't be possible for multiple to be visible/open at once.
foreach ($available_autocompletes as $autocomplete) {
if ($autocomplete->isVisible()) {
$matched_element = $autocomplete->find('xpath', "//a[text()='${popup}']");
if (!empty($matched_element)) {
$matched_element->click();
$this->contexts['mink']->iWaitForAjaxToFinish();
}
}
}
throw new \Exception(t('Could not find autocomplete popup text @popup', array(
'@popup' => $popup)));
}
}
@ABGEO
Copy link

ABGEO commented May 18, 2020

You can simply use Given I fill in "My Autocomplete Value" for "my_autocomplete_field"

@swichers
Copy link
Author

swichers commented May 18, 2020

@ABGEO That does not actually simulate typing into an autocomplete. If you're trying to validate that the autocomplete actually shows the suggestions you are expecting you need to fake typing into one as opposed to setting the field value in one go.

For example, Given I fill in "My Autocomplete Value" for "my_autocomplete_field" will succeed even if JavaScript on the page has failed to load. It will succeed even if there are no suggestions that match what was entered.

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