Jasmine Headless vs In Browser

In the last couple projects, we’ve been using Jasmine for our Javascript testing. It’s been great. Tying that in with jasmine-headless-webkit has made our Javascript testing super fast for both development and our CI box.

One problem we’ve hit a couple times is differences between the real browser and the fake browser (headless-mode). For example: in the real browser, you can build an iframe with a src attribute and it will do the right thing.

$('body').append(
  $('',
    {src:'http://embedded_page.example.com'})
);

However, if you run this through your headless tests, depending on where this code is executed, you may get errors like this from jQuery:

Fixture could not be loaded: spec/javascripts/fixtures/recipe_subnav.html
(status: error, message: NETWORK_ERR: XMLHttpRequest Exception 101)

or like this from the Jasmine framework:

Can't load file:///projects/myproject/specrunner.11688.html, the file may be broken.
Out of curiosity, did your tests try to submit a form and you haven't prevented that?
Try running your tests in your browser with the Jasmine server and see what happens.

Certainly, we could probably stub out a bunch of stuff to make this fly, but sometimes time is better spent pushing forward. To get around this, we wanted a simple way to check for the command line tests vs in browser tests. We added to our SpecHelper.js file:

var is_headless = function() {
  return (/jasmine-headless-webkit/.test(navigator.userAgent));
};

With this now in place, we can write tests like this:

describe('save scroll top cookie plugin', function() {
  beforeEach(function() {
    loadFixtures('my_fixture.html');
    $('body').scrollTop(123);
    $('#fixture').saveScrollTopCookie();
  });
  if(is_headless()) {
    it('it sets a cookie for scroll position', function() {
      expect($.cookie('scrollTop')).toEqual('123');
    });
  }
  it('does something else', function() {
    expect(somethingElse).toBe(true);
  });
});

With this setup, instead of missing tests because we’ve constructed a bunch of xit or xdescribe blocks, we can keep all the tests around, and simply skip those that don’t lend themselves to the specific situation (in-browser or headless).

It is not something that is used a lot, because we really strive to make tests which are universal, but in those special cases where we still may want a spec, this simple helper method works pretty nicely.

Advertisements

Fauxtaux Booth – our Mashup-o-rama

We’ve been noticing that writing software for the web is becoming more and more like playing with lego blocks. We are currently working on projects using Ruby + Rails and Node.js + Express. For both of these technology stacks we have a lot of conversations like these:

“You need a library that does <this special thing>?”
“Oh yeah, it’s on github.”

“You need a javascript plugin that does <whatever>?”
“Sure, start from that thing on jQuery plugins and you’re 95% there.”

Such is the nature of participating in and taking advantage of the open source community.

We wanted to share our latest lego-block project. We called it

Fauxtaux Booth

A photographer friend was setting up a photobooth at a conference. She wanted to have the pictures sent directly to the subjects as they were being taken.

The blocks we used for this system were:

The basic setup was as follows:

The photographer was on the net at the conference, her camera tethered to the laptop. As photos were taken, they were written to a folder that sat under a shared Dropbox folder.

On a separate server, also sharing that same Dropbox folder, we setup a watch on that folder using Guard. When we saw a change, we sent an http request (basically a ping) to the Rails app. When the app caught that http request, it would look at the directory and figure out what had changed. If there were new images, it would run several image processing steps and finally email the current customer by way of Sendgrid.

The app also served as a customer signup form. So at the conference, the photographer’s laptop also had a browser window open to the app. As customers stepped up to the booth, they filled out a simple form on the laptop with name and email which we used to send the photos.

For each sitting, the final emailed image was a photostrip with the conference’s branding/data on it.

The majority of the special coding in the app was custom image processing. The rest was basically wiring a bunch of moving parts together.

At the event, our photographer took about 80 photos and we sent out about 400 emails.

This was the setup at the conference.