Testing, Web Development

Creating cross-browser extensions with Crossrider

Last year I had the opportunity to work on the development of a browser extension for multiple browsers. As I wanted to minimize the amount of browser-specific code and wanted to avoid duplicating my extension for every browser, I used the Crossrider framework. This post provides an overview of my experiences with developing a cross-browser extension using the framework.

The requirements

The extension I had to create was meant to search through web pages as the user visited them and then add some extra functionality to certain keywords on the page. I won’t go into details here, but it’s something similar as Skype’s Click to Call, which does the same with phone numbers: Click to Call recognizes phone numbers and adds a button to the webpage to easily call this number through Skype:

Skype Click to Call in action - copyright www.skype.com

Skype Click to Call in action – copyright http://www.skype.com

Some high-level requirements for the extension were:

  • Support multiple browsers (without having to maintain completely different versions of the extension)
  • Easy distribution channels for installing the extension and pushing out updates to your users.
  • Support for background processing. Scraping a web page takes time, this processing should be done without affecting the browsing experience for the user.

Support for multiple browsers

The extension had to be supported on Internet Explorer, Chrome and Safari. Most of these browsers enable developers to write extensions using plain HTML/JavaScript (except Internet Explorer, which requires you to dig up your C++ skills) and each of them have different API’s to communicate with the browser itself. I had two alternatives here:

  1. Write a common codebase and write some browser-specific glue code to wire everything up for each individual browser.
  2. Use one of the cross-browser extension frameworks that take care of the browser-specifics for you and provide a single API to develop against.

The first option did not appeal to me because I had limited time and little interest to learn each browser’s specifics, so I decided to go for the latter. I investigated several options (KangoExtensions, FireBreath and Crossrider) and Crossrider came up on top for my specific needs.

Setting up your Crossrider development environment

The development setup for Crossrider is easy: you develop your extension in Javascript/jQuery, HTML and CSS. For everything browser-related, like having a button in the toolbar or background processing -in browsers that don’t support Javascript Web Workers, I’m looking at you IE 9.0!-, you use the Crossrider API. Crossrider builds your extension for you phonegap build-style: you provide your source files, they build the app for each browser and you just have to press the “install extension” button on their site.

New to modern web- and Javascript development, I decided to start things off on the right track by setting up a source control repository and configuring a unit test framework (QUnit). All set up and eager to start, I tried creating the obligatory “Hello world” extension in this setup. This turned out to be less trivial than I had anticipated. Crossrider’s most common mode of development is by using their web-based in-browser IDE. Developers can log on to the site and fiddle around with their source code in the web IDE. From this web IDE, they can install the extension in their browsers for manual testing. This feedback loop was too lengthy for me. I didn’t like the notion of not having any automated tests either (sidenote: following a recent discussion in the software testing community, some people may call this automated checks. Call me old-fashioned but that just doesn’t have the same ring to it, so I’ll stick with the prehistoric jargon).

Getting your code under version control

Crossrider does however offer nice support for offline development. All you have to do is:

  • Host a local web server that grants local http access to your source code (I used the lightweight and easy to use mongoose).
  • Install a “local development” version of your browser extension in your favourite browser. This special version uses the scripts hosted by the web server you set up in the previous step.

This allows you to develop your extension in Visual Studio, Eclipse or whatever flavour of IDE you prefer. You can just save the changes in your local javascript source files, press F5 in your browser and immediately see how the new version of the code behaves in a running extension. Developing in this setup makes it easier to put your code under source control, without constantly having to download your entire codebase from the web IDE (a feature Crossrider supports, by the way). When it comes to releasing a new version of your extension to your users, you can just zip your local codebase, upload it using the crossrider web IDE and press “push to production”. Simple as that.

Supporting automated testing

I had my source code under version control, but I was still missing another crucial aspect of my setup: automated tests. This also proved to be less straightforward than I had initially anticipated. Since crossrider does the compiling for you, you don’t have access to the Crossrider source code or binaries. This results in a situation where you have your code which requires the crossrider API to function correctly, but you have no access to the Crossrider API, be it sources or binaries, on your local machine. I know that mocking out all external dependencies of your system under test is considered a unit testing best practice, but this situation effectively forced me into stubbing out all dependencies on the Crossrider framework for my local unit tests. Javascript, being a dynamic language, made stubbing the API very easy. I did not have to write a wrapper interface around the Crossrider API to provide an abstraction point where I could inject my stub during testing, I could just provide my own definition of the API which I included during unit testing and everything worked out nicely. You can find a simple hand-rolled Crossrider stub for all the functionality I needed here. It does not cover the complete API, so feel free to extend and/or modify it to your needs. This stub also allowed me to run my code as if it were running as a Crossrider browser extension, which allowed me to do manual exploratory and user-experience testing of the entire codebase, without constantly having to upload my source code and installing the extension in all my test browsers.

Other issues I faced

With the setup described above, I quickly fell into my usual development cycle: write the next failing test – implement the least amount of logic that makes the test pass – refactor. Oh, and since were talking about web development: manually verify the look-and-feel of the new change in my preferred browser. Initially I only used Chrome to run my tests and to check the visuals, as it offers the best out-of-the-box web developer toolset I have come across (just watch the video here if you have any doubts). That was a bad idea. After several days of development, I ran my code on the other supported browsers and it didn’t work. What happened? Had I not carefully set up my environment? Did I not have a battery of unit tests at my disposal? After some debugging (and let me tell you, Internet Explorer’s developer tools are not as pleasant to work with as Chrome’s) it dawned on me: I was still writing HTML and Javascript, so all the usual web development quirks still applied.

Here is a non-exhaustive list of issues I faced:

  • Browsers do not allow cross-domain requests out of the box. You can call this secure, but it’s also painful to work with. This is especially the case when you’re developing a browser extension that will be making cross-domain requests by design, as any calls to your own web server will be coming from the site you’re visiting. If you are having problems with cross-domain requests, you might want to check out my post on that topic here.
  • Internet explorer does not implement common Javascript functions like Array.indexOf. Issues like this are problematic if you didn’t know these differences between JavaScript implementations in browsers existed, but they are easy enough to deal with.
  • The look and feel of your HTML/CSS can be inconsistent across different browsers. What I recommend: don’t use any esotheric CSS (examples and their compatibility in different browsers can be found here) and at least check the visual end result in all of your supported browsers.

On Crossrider itself

With Crossrider being a relatively young framework it has the same problems all startup-technologies face: an unstable API (optional method parameters suddenly became required in some browsers), some minor regressions, etc. I can understand where these issues come from (and as a result I can live with them): supporting several browsers, each of which develops rapidly, is no mean feat. These issues have however greatly improved in the last year (i.e. I did not run into any Crossrider-specific issues lately). This also brings me to one of the major benefits of using Crossrider: their great support. You can ask the development staff direct questions on their support site and they will assist you swiftly. Of all the issues I logged, most of them were resolved in a mere couple of days.

Like jQuery, Crossrider provides a nice layer of abstraction for several browser quirks like the cross-domain requests I mentioned above. The problem is, you have to know these quirks exist first. I remember when I first scrolled through the Crossrider API and saw functionality for accessing local storage and performing Ajax requests. My first thoughts were “Why would they provide an API for this default behaviour?”. After having experienced web development on multiple browsers first-hand, I can now relate and appreciate these kinds of things.


Developing this extension was my first real contact with web development. As it turns out it’s not all about creating fancy HTML and CSS and hacking together some JavaScript through trial-and-error. You can still apply design patterns -heck, with functions being first-class citizens in JavaScript you can do some really cool stuff!-. You can still run automated tests. Writing JavaScript is very rewarding, as you can immediately see the end result of your changes. Because it’s an interpreted language, you just have to save your changes and hit ctrl+F5 in your browser. No compilation needed! (Although, with TypeScript around the corner, this may change in the future)

As for using Crossrider: If it covers all your cross-browser requirements I can only recommend it. It provides a nice abstraction for different browser implementations and offers easy distribution of your extension and a near painless installation procedure for your users out of the box. If you want to take the responsible route -by which I mean versioning your code and adding automated tests- it’s possible but it will take some setting up.

Just don’t go thinking you’ll never have to leave your sweet Chrome developer tools, as you’re still just writing JavaScript, hereby having to face all the usual browser quirks.


2 thoughts on “Creating cross-browser extensions with Crossrider

  1. Viktar says:

    Don’t forget to mention that Crossrider is free and Kango is commercial and it costs thousands of dollars to add IE support.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s