End2end Testing Ionic collection-repeat with Protractor

featured-image-blog

 

I have been recently building out the end2end test suites for our MobileCaddy Seed and Shell applications. The core goal was to give Salesforce mobile application developers a starting point on which they could add their own test suites and specs, giving them a head-start when end2end testing Ionic apps. During this process I ran into a couple of “gotchas” when dealing with Ionic’s collection-repeat directive. This post should highlight the issues, propose some work-arounds and also lay the outline on how we rectify the issues we’ve seen.

This post assumes you know about Protractor, if not you can read up here, but the long-and-short is that it’s a testing tool built for AngularJS applications. It is assumes you are familiar with Ionic’s (incredibly brilliant) collection-repeat directive.

The Scenario

I’m going to use our Time & Expenses mobile application for Salesforce as our example (you can download it from github). The main screen of our application simply lists projects that are assigned to our currently logged in user. This list uses Ionic’s collection-repeat to populate the DOM with our projects, and with our application in test mode the list should contain 5 projects. What I want to do is use Protractor to end2end test that our app starts up and that this screen has 5 projects listed.

Salesforce Project List

With this in mind our application code looks something like this;

And our test like this;

We’re using the repeater locator to pull out the list of items in our collection-repeat and then we’re checking this against our expected number of projects… or at least that’s what we wanted to do.

The Issue(s)

After running our protractor test we run into the following error;

So what happened? Well actually Protractor doesn’t support collection-repeats in it’s repeater locator. That’s OK right because we can work around this and use a different locator perhaps. In our case we can use the binding locator and look for project.Name. This could be the first stab at our new code;

Let’s run our test again, and this should work right?

Wrong! Here’s what we get;

Where did that count of 20 come from? We only have 5 projects.

After digging into the Ionic code I can see that collection-repeat currently creates 20 DOM items, regardless of if there are less or not.

Hmmm… so what can we do?

The Work-Arounds

The first step, mentioned above, is to use an alternate locator instead of repeater. But this only takes us so far.

The second step (which is admittedly ugly) is to spec our test like this;

Now we’re using the binding locator and also checking that the 5th element has some content and that the 6th is empty. Of course this is not ideal, but hey, this is a work-around right… and does it work?

Woohoo!

Our (planned) Solution

There are actually two prongs to what we’re going to do to make this nicer and better;

1) Pull Request to Ionic for collection-repeat

We currently have a PR submitted to Ionic to dynamically scale the number of DOM elements created in a collection-repeat. This will remove the need to check, for example, the content of elements that shouldn’t really exist.

2) Create a protractor-ionic-locator Package

UPDATE: We have launched our protractor-ionic-locator package… check it out. This adds a custom locator to select collection-repeat lists (with more locators to follow)

We’ll update as both of these progress… but in the meantime we hope that our write-up here might save you some time when end2end testing Ionic mobile applications.