Jaeger
Jaeger

Reputation: 1754

Issues with Drupal's autocomplete test with Behat

I'm trying to test a form generated by Drupal where there are some autocompletion to help people do the right choice.

In this form, there are 3 fields that let the user select 3 articles ('Actualités'), and once you start typing things, the auto-completes generates a list of Articles that have a similar title.

Here is an example:

behat1

The problem is that I realized while doing some tests that using $this->getSession()->getPage()->fillField() makes Behat loose focus on the field, like if it presses Tab once done filling the field.

So I tried a lot of tricks to gain focus of this field, like the following:

$field = $this->getSession()->getPage()->findField('field_mb_actualites[0][target_id]');

if($field) {

  // Solution #1
  // the dropdown menu is inside a `ul#ui-id-1` element
  $this->getSession()->executeScript("jQuery('#ui-id-1').show();");

  // Solution #2     
  $field->focus();

  // Solution #3
  // Consists of pressing "shift + tab" for a "reverse tab" and trying to get back to the field

  $this->getSession()->getDriver()->keyDown($xpath, 16);
  $this->getSession()->getDriver()->keyDown($xpath, 9);
  $this->getSession()->getDriver()->keyUp($xpath, 9);
  $this->getSession()->getDriver()->keyUp($xpath, 16);

  // And I take a screenshot at the end to see if anything worked
  file_put_contents('screenshot-focus.png', $this->getSession()->getDriver()->getScreenshot());
}

But I always get the same result, which is the following:

behat

All I need to do once I have the focus is to press the "right" directional arrow to make the dropdown visible again, then the "down" directional arrow to select a suggestion, then "Enter" to confirm the choice.

However, I'm starting to run out of ideas, even though I found a couple questions on Behat's github about this problem, but I couldn't manage to make the answers work. How can I trigger the auto-complete?

Thank you in advance

Upvotes: 0

Views: 326

Answers (1)

lauda
lauda

Reputation: 4173

You can use a JavaScript function to trigger the event like this:

    public function triggerEventOn($css_selector){
        $function = <<<JS
        (function(){
        var element = document.querySelector("$css_selector");
        var event = document.createEvent('Event');
        event.initEvent('change', true, true);
        element.dispatchEvent(event);
        })()
JS;

        try{
            $this->getSession()->getDriver()->executeScript($function);
        }catch (Exception $e){

        }
    }

If you want you can also adapt this to fill the field and trigger the event after. For checking the event that you need to trigger you need to inspect that element and check that ev in the inspector.

Upvotes: 1

Related Questions