Search code examples
capybarapoltergeist

Capybara/Poltergeist, expanding Accordion Table expanding intermittent failure


I have an issue with expanding a table/row. I did some googling and haven't found any information on such a scenario.

Basically I have a table with 5 or so columns. When clicked on will expand the table and reveal more information. Inside this new information is a button im trying to click on.

Here is the HTML for the row for the table iself:

<thead>
 <tbody>
  <tr class="odd" data-row="0" data-source="/user/01" role="row">
   <td class="sort_1">John Doe</td>
   <td>Person</td>
   <td>Yes</td>
   <td>Yes</td>
   <td> Building 2 </td>
  </tr>
<more table rows here repeated>
</tbody>
</table>

The table html itself has an id and everything, but I need to click on any one of the columns within the row itself to get it to expand.

I tried this: page.find('td', :text => 'John Doe').click and while it did work successfully, after taking a screenshot it didn't seem to show anything expanded...so im not sure an expanding table will work in this instance. HOWEVER upon re-running it , it worked....but it's not consistent.

The screenshots that poltergeist show have the expanded table barely showing (like just a sliver of expansion). So maybe it's not waiting enough time for it to appear? Im not sure.

When the table expands it basically makes a new <tr user-data-row="5"> that will appear underneath the row above when expanded.

For reference here is the HTML for the button that I click after expansion:

<div class="col-xs-12 col-sm-5 col-md-5" style="">
 <ul class="list-unstyled">
 <ul class="list-inline">
  <li>
   <a class="btn btn-sm btn-default" href="/stuff/site" data-method="post" rel="no-follow" data-confirm="Generic: Confirmation Dialogue">The Button</a>
  </li>
  <li> </li>
 </ul>
</div>

I thought at first that it was tripping up on the confirmation dialogue popup, but Poltergeist is supposed to avoid those by default. And it seems to do that....so Im not sure what could possible be the problem. With it being inconsistent Im thinking possibly it's a timing issue. My Capybara.default_max_wait_time = 15 since the DB is on a VM, but it hasn't been an issue so far....

Edit: The code that fails seems to be after this: page.find('td', :text => 'John Doe').click click_link('The Button')

It seems to work about 50% of the time.


Solution

  • When using some Capybara drivers with animations it's possible for clicks to miss their targets. This happens because the location for the mouse click to occur is calculated, the mouse event is created, and submitted to the "browsers" queue for processing. Before the event is processed it's possible for the destination element to move enough that the click misses the element. There are a few ways to handle this

    1. The best solution all around (speed, reliability, validity of mouse events) is to disable animation in the test environment. This can usually be done by conditionally setting a few JS variables depending on the libraries being used.

    2. Sleep for a small time before attempting to click so the animation has time to complete - This is slower, but still keeps "real" mouse clicks that travel through the pages event processing like a users would.

    3. Use #trigger to simulate a click - element.trigger(:click) - this will be quick but can short circuit of lot of things that are done to make sure tests validly replicate what a user can do and can therefore lead to tests that miss failures. It should be used as the method of last resort