Using RSpec to Assert Model Order in Capybara Rails View Acceptance Test
Last Updated: December 20, 2018
DoggieDashboard is getting more tests than you can shake a stick at. We're currently around 800 tests, and those are just controller and model tests. I'm just starting to get serious about acceptance tests with Capybara. One of the features of the DoggieDashboard check-ins page is that you can reorganize your currently checked-in pets by oldest check-in first. This is in contrast to the default view which is alphabetically organized by pet name. There's a jquery link that can be clicked to reorganize the currently checked-in pets. In order to test this button with Selenium, I'd need to be able to figure out how to make sure that certain check-ins showed up higher on the list, even if they had last names that started with later letters. For those of you that are visiting the page, I'm sure you've realized that checking the order of elements can be quite tricky. You're either using CSS selectors and trying to crawl across the page to find these selectors, or you're string together some other method. Based on this post by Launchware, I got the idea to start using the string index method on the Capybara body HTML text.
Here is the basic layout of the DoggieDashboard check-ins page. Pets that are currently checked in are listed by their name in alphabetical order. This makes it easier for pet business owners to find the pet they're trying to check out at any given moment. However, a user requested a feature to sort their check-ins by the oldest first and I thought it was a good enough idea to put into action. I didn't have tests for it until today though. ¯\_(ツ)_/¯
Here you can see the Capybara body text after all three check-ins are created. You can see that the check-ins are ordered by pet names, which means the default sorting is working out properly (even if the pets aren't checked in in that order). Using the index, I can check the order after clicking the "Sort by Check-In Time" button.
The next part of the process was writing up the acceptance test. I have created some simple methods that check-in pets for me and do other basic tasks in my RSpec tests. After checking in all three pets, I make sure that Abbie is listed on the page before Maggie and that Maggie is before Zulu. This means that they're currently organized alphabetically by pet name. After clicking on the "Sort by Check-In Time" button, you can see that I recheck to make sure that Zulu is first, followed by Maggie and then Abbie. This verifies that the pets are properly listed by who was checked in first.
In the image below, the "Sort by Check-In Time" link has been clicked. It disappears from the page and the check-ins are now sorted by their check-in time, instead of pet name.
If you're having trouble using RSpec to check the order of your models on a page, using the Ruby index method is one of the biggest helps I've found so far. It isn't a sure-fire win, since there might be some edge cases that get by you, but it works quite well out of the box.