Protractor Testing with Google Map Markers and Markerclusterers, Part 3

In this final part of this post, we will be locating the cluster markers (from the  Markerclusterer or MarkerclustererPlus library) in a Google map. This is in the context of e2e testing for an AngularJS web application using Protractor.

The first part of the post was a brief introduction , while part 2 showed how to locate Google maps markers.


The cluster markers have this DOM structure.

<div class="cluster">
    <img />

Once again it is just a case of finder the right xpath expression to use as the locator. If we were only interested in the number of cluster markers on the map, we could just use the count() utility method for the ElementArrayFinder as we did for getting a count of the Google maps markers.


However for the application I was working on, I needed the total number of markers represented by all the cluster markers.

The cluster marker div structure has an inner div that contains a number, this is the number of Google map markers that are not shown but are represented by the cluster. So here we have to get this number from all the cluster markers and add them up.

ElementArrayFinder has various functions such as each() and map() that would allow us to either iterate through the cluster markers and extract the information we need so that we can total the numbers. Luckily it also has a reduce() function that does exactly what we need, and here is an example of a spec test using it.

var checkClusterNumberCount = function(expectedCount) {
    element.all(By.xpath("//div[@class=\"cluster\"]/div")).reduce(function(accum, elem) {
    return elem.getText().then(function(text) {
    var num = parseInt(text);
    return accum + num;
}, 0).then(function(result) {

The explanation for this function:

1. The xpath expression is used to locate all the cluster markers in the DOM.


2. The function element.all() returns an ElementArrayFinder and the reduce() function is called. In this case it is passed our own reduce function that has 2 parameters:

  • accum holds the accumulated number, which is initially set to zero
  • elem is an ElementFinder from the ElementArrayFinder

3. For each ElementFinder we call the getText() to get the value from the inner div. This value is converted to a number and added to the accumulated number. Notice that since ElementFinder is also a promise, we need to use another callback from the getText() function.

4. We then use the expect() function to compare the final accumulated number to the number that we were expecting in order to pass the test.

Final Tip

Initially after I ran the code to count the markers (both the displayed markers and the ones contained in the cluster markers) I found that, although the code was working properly, some of the tests would occassionally fail. Eventually I worked out that even though in the callbacks the AngularJS code may have finished running, I still sometimes needed to wait for markers and markerclusterers to finish loading in the map.

I worked around this by added a small delay before trying to locate the markers, e.g.

This is a bit of a hack, but unfortunately I’m not aware of any way to get a notification from Google maps when markers have finished loading.

Protractor Testing with Google Map Markers and Markerclusterers, Part 2

Part 1 of this post was a brief introduction about the Protractor spec I was working on, where I had to locate markers and cluster markers in a Google map . In this second part, there are some tips on how to find those Google maps markers.

Firstly, I must give credit to this blog post which had similar ideas about finder Google maps markers for Selenium testing.

Configure the marker

Most importantly, when the marker is created it must be configured as being unoptimized. This means the markers are created as elements that can be located in the DOM.

 var marker = new google.maps.Marker({
   position: latLng,
   title: 'your title',
   optimized: false

Be aware that using unoptimized markers should only be done for development and testing, as it significantly affects performance.

In the spec test we can use xpath to find the div’s that represent the markers, but the specific xpath expression will vary depending on various factors, such as whether the marker has events attached to it. For example you may want to have a click event attached to the markers, so that something happens when the user clicks on the them.

google.maps.event.addListener(marker, 'click', function() {
  // do something

Another factor that affects how the DOM structure for a marker is rendered, is the platform and browser that the web page with the map is running on.

The best way to formulate the xpath expression you want to use as the locator for the markers, is to use a web inspection tool to have a look at the DOM element(s) for the marker. This should be done for the browsers and platforms that you want to support.

Markers without Map Areas

The first marker DOM structure has a div that looks like this.

<div title="your title" class="gmnoprint">
  <img />

Some examples of situations where the markers that have this structure include:

  • Chrome (Windows), markers without events
  • Firefox (Windows), markers without events
  • Chrome (Android), markers with events

In the example I’m using for this post, the test spec is locating the markers in order to get a count of all the markers in a map.

element.all(By.xpath("//div[@class=\"gmnoprint\" and @title]")).count();

Several things to note here:

1. The xpath expression is used to locate all the markers in the DOM.

By.xpath(“//div[@class=\”gmnoprint\” and @title]”)

2. The function element.all() returns an ElementArrayFinder and has various utility methods such as count().

3. Since ElementArrayFinder is a promise, if you need to get values from the marker elements you need to use a callback.

For instance if you wanted to get the titles from the markers:

var titles = element.all(By.xpath("//div[@class=\"gmnoprint\" and @title]")).map(function(elem, index) {
  return {
    index : index,
    title : elem.getAttribute('title')

Markers with Map Areas

Another marker structure is where the div contains an <area> tag inside a <map> tag.

<div class="gmnoprint">
  <img />
    <area title="your title" />

You may encounter this DOM structure in the following:

  • Chrome (Windows), markers with events
  • Firefox (Windows), markers with events

Once again we can get a count of the markers using a xpath expression to match the DOM structure for these markers.


In the final part of this post, I will show how to find the cluster markers in the map, and also how to find the number of Google maps markers represented by each cluster.

Protractor Testing with Google Map Markers and Markerclusterers, Part 1

While doing e2e testing on an AngularJS app using Protractor, I came across the need to find the markers in a google map within the app. This was further complicated by the fact that we were using MarkerclustererPlus, which meant on the map there could be a mixture of single markers and cluster markers.

This first part is just a bit of an introduction, so if you want, you can go straight to Part 2 which shows how to find the Google Maps markers in a Protractor spec or Part 3 for using markerclusterer.

What is a Markerclusterer?

If you are not familiar with markerclusterers, it is a google maps utility library which deals with maps that have too many markers or are too cluttered, by combining markers that are close together into cluster markers. Have a look at the example page:

Also note there are actually 2 libraries, markerclusterer and markerclustererplus.

I’m assuming that the reader is already familiar with setting up and using Protractor for testing AngularJS applications.

AngularJS and Google Maps

Being an AngularJS app, I decided to use a directive to create the Google map.

There are a few AngularJS map directive libraries around, but the one I decided upon was ng-map.  The advantage of this particular library was that although you can just use its tags to create the map, it also allows you to use the Google Maps V3 Javascript API directly. This is very useful, for instance even though there was a markerclusterer tag, I just wrote the code in Javascript which was more flexible and easier to debug (the author of the library also seems to recommend this approach for complicated code).

So for this application, the map libraries that were used were:

Count the Markers …

The spec file I was working on needed to count the number of markers that were displayed on the map. Now as I mentioned earlier, because I was using the markerclusterer library, the markers could appear as single markers (i.e. the default Google Maps markers) or as cluster markers, and the number of markers and clusters would vary depending on the zoom level of the map.

Therefore in the tests I needed code to find:

  • single markers
  • cluster markers
  • the number of markers contained in each cluster marker

In the next post, I will show how to find the single markers displayed on the map. All you will need are web tools that can inspect elements in a web page, such as Firebug or the Chrome Developer Tools.

Android Fragmentation – A Developer’s Perspective

Much has been written about Android fragmentation, and how it affects consumers. But what does it mean for Android developers?

Well, more testing – lots more testing. And, of course, all the associated support and bug fixing issues for dealing with multiple versions.

You have to test for:

  • All the Android versions that you want to support for your app.
  • Then there is testing for different screen sizes (both in portrait and landscape mode, of course, and handling orientation changes between them).
  • Also testing for manufacturer phones that have a custom UI, especially if your app interacts with the UI in some way – for instance for widgets or if the app accesses system settings screens.

This sounds like a lot of work, and it is, if you are diligent about testing and providing a good experience for your users.

But then is this much different for developers writing web applications that work in browsers?

In that case you would have to test your app for:

  • All the major browsers that you want to support (Firefox, Internet Explorer, Chrome, Opera, etc).
  • Different versions of these browsers that might still be in use (and how to degrade gracefully for older versions).
  • Once again different screen sizes, particularly if you are supporting mobile devices as well as desktop.
  • Exception testing in cases where the user has disabled Javascript or is not using cookies.

So, from a developer’s perspective it’s not all that different from the issues that Android developers have in terms of having to do a lot of testing and app support.
They just don’t call it fragmentation, because it isn’t. But the issues with having to support multiple client environment versions are the same.

I consider that this is the price that has to be paid for working on systems that have some degree of ‘openness’ (in contract to systems that are tightly controlled by the company that owns it).

If you support openness in software, then I think this is a price worth paying.

Update 7/3/2015

Recently I have been investigating web (Javascript) frameworks to use for an upcoming project.

Then I came across this post about how bad fragmentation was in that area. Basically the gist of the article was that there were so many frameworks and libraries for building web applications, and the landscape was constantly changing. The author used the phrase ‘crisis of churn rate‘ to describe the mess.

Even frameworks like angularjs, which seems to have a lot of mind share at the moment, will have a new version (2.0) coming out possibly at the end of the year which will not be backwards compatible with the current version. More fragmentation!

After having read that post, and done a bit of research myself, it just reinforced my view that Android fragmentation was not really so bad after all.

Now, which Javascript framework/library/tool/combination should I be using …

Flash – don’t shoot the messenger

I have been reading that Adobe is stopping development of Flash for mobile devices (official announcement). If fact there have been many recent articles lately about the demise of Flash in general, they seem to argue that Flash is a ‘bad’ web technology and should be dumped in favour of HTML 5.

One of the reasons cited for Flash being bad was that it is used to create those annoying ads and banners. I think this is confusing the Flash technology itself with its usage – in other words blaming Flash when the real culprits are the purposes to which people have used it (or abused it).

As a former web developer, I remember that before Flash came along there were equally annoying popups and banners being produced using animated GIF’s. I suppose if Flash were to go away we would still be getting those annoyances using whichever is the current web animation technology of the day

Don’t get me wrong, I know that Flash technology does have real issues regarding stability, performance, etc – but then just about every web technology has its problems (including HTML when being used to create interactive web applications).

Luckily there are also other articles with a more balanced view, e.g. “Adobe Flash: Still the 800-Pound Gorilla”.