Testing AJAX autocomplete fields with cucumber and capybara
Recently I had to write some cucumber scenarios which featured an AJAX autocomplete. As this seemed not to be pretty straightforward and I didn’t know how to test the autocomplete I had to step out of my TDD flow and start by writing the code first. In order to implement the autocomplete I used the widget included in the jQuery UI library.
Once I knew the feature was working I sat down and wrote a cucumber scenario for it. Let’s look at what the expected behaviour:
- Type in substring, e.g. “Madr”
- Get list of options, e.g. “Madrid, Spain”, “Madridejos, Spain”, etc.
- Click on the option we want to select, e.g. “Madrid, Spain”
- We expect the field value to be set to the selected string, e.g. “Madrid, Spain”
At the beginning my cucumber scenario looked something similar to this:
The first thing to take into account is that we have an AJAX scenario, so we can’t rely on the standard rails driver and we are forced to use a driver that supports AJAX like envjs, culerity or selenium.
This scenario above won’t work just like that for several reasons:
- the “I should see…” step won’t work because it won’t update the DOM before checking for the text’s presence.
- the “I follow…” step relies on the standard web_steps.rb step definition. This looks fora tags with an href attribute and the jQuery autocomplete generates a tags without href since it doesn’t need to link anywhere.
In order to tackle the first problem we can try different strategies:
1. Wait for a few seconds using a custom reusable step and then try to launch the “I should see” step:
2. Implement a custom step to check for such links and use capybara’s locate method which will wait up to a certain time for the content to be there.
This would look like something like this:
Now on to the second problem. We need to implement a custom step to click such links. In my case, since I am using the autocomplete form jQuery links are wrapped in li elements and do not have href attributes.
This is the sample HTML code for one of such links:
<li class=”ui-menu-item” role=”menuitem”><a class=”ui-corner-all ui-state-hover” tabindex=”-1” id=”ui-active-menuitem”>Madrid, Spain</a></li>
I tried a few different strategies here. Just clicking didn’t work. Googling for the problem brought up some results after some time and I found out I needed to trigger the ‘mouseenter’ event. Finding out how to trigger such events depends on the driver you are using. In my case the only way I got it work was to evaluate some JS code that triggers the events within selenium. I didn’t get this running on culerity or envjs but if anyone knows how to do it please share it. I don’t like relying on selenium if there is a faster option.
This is how I ended up dealing with the autocomplete clicking: