Friday, October 11, 2013

Checking Jquery Ajax requests from Capybara

I was working in a particular feature today. I wanted to test an autocomplete input box that makes its requests via Ajax. Something very common.

I wanted to test that the requests were being done to the right URL in a black box kind of way using the cucumber features.

This is what I did:

  • First added a new visit method visit_tracking_ajax to my Cucumber environment with the following content

    module CucumberGlobals
     def visit_tracking_ajax(url)
      visit(url)
      page.execute_script("$(document).ajaxSuccess(function(a,b,c){console.log(this);window._latest_ajax_url_called = c.url;})")
     end
    end
    
    World(CucumberGlobals)
    

This executes a Javascript Jquery script in the page that will listen to every Ajax request being made (through Jquery) and set a variable on window with the URL called in that request.

  • Then from my step definition I did something like:

    page.latest_ajax_url.should == 'http://www.xx.xxx'
    
  • Having also added the following method to the Capybara session:

    module CustomMethods
     def latest_ajax_url
       evaluate_script("window._latest_ajax_url_called")
     end
    end
    
    module Capybara
      class Session
        include CustomMethods
      end
    end
    

That's it, now I was checking the last ajax url being called. This is fragile code, but it worked fine for my current use case.

Monday, October 7, 2013

Simple setup for testing MongoDB map reduce with Ruby

Simple setup for testing MongoDB map reduce with Ruby

This is a superquick tutorial to running Mongo Map Reduce aggregations from Ruby. This is as simple as it gets. A MongoDB running locally and a unique Ruby script. For the test I created the follwoing simple collection in a Mongo DB called example

> db.values.find()
  { "_id" : ObjectId("52530971a1b6dd619327db27"), "ref_id" : 1, "value" : 2 }
  { "_id" : ObjectId("5253097ba1b6dd619327db28"), "ref_id" : 1, "value" : 4 }
  { "_id" : ObjectId("52530983a1b6dd619327db29"), "ref_id" : 2, "value" : 10 }
  { "_id" : ObjectId("52530989a1b6dd619327db2a"), "ref_id" : 2, "value" : 15 }
  { "_id" : ObjectId("52531414a1b6dd619327db2b"), "ref_id" : 3, "value" : 100 } 

Then I created a simple Ruby project with the only entry gem "mongoid" in the Gemfile.

The following mongo.yml configuration file:

development:
  sessions:
    default:
      database: mongoid
      hosts:
        - localhost:27017

The Ruby script is then

require 'mongoid'
Mongoid.load!("/Users/cscarioni/ossources/mongo_map_reduce/mongo.yml")

session = Moped::Session.new([ "127.0.0.1:27017"])

session.use :example

map = %q{
  function() {
    emit(this.ref_id,{value: this.value});
  }
}

reduce = %q{
  function(key, values) {
    var value_accumulator = 0;
    values.forEach(function(val){
    value_accumulator += val.value
  });
   return {val: value_accumulator} 
  }
}


puts session.command(
  mapreduce: "values",
  map: map,
  reduce: reduce,
  out: { inline: 1 }
)

When running the script, we get the following results:

 MONGOID_ENV=development ruby mongo_map_reduce.rb


{
  "results"   =>   [
    {
       "_id"         =>1.0,
       "value"         =>         {
          "val"            =>6.0
       }
    },
    {
       "_id"         =>2.0,
       "value"         =>         {
          "val"            =>25.0
       }
    },
    {
       "_id"         =>3.0,
       "value"         =>         {
          "value"            =>100.0
       }
    }
 ],
  "timeMillis"   =>13,
  "counts"   =>   {
    "input"      =>5,
    "emit"      =>5,
    "reduce"      =>2,
    "output"      =>3
  },
  "ok"   =>1.0
}

That's it. A quick example. Sometimes it is more convenient to use a Ruby script than deal with the Mongo Json shell interface.