public
Last active

Integration testing of google analytics/kissmetrics script.

  • Download Gist
README.md
Markdown

To easily explain, imaging you are developing google analytics or kissmetrics and you need to do integration testing of the javascript file. That's the file which people include on their website. Assume client also needs to push some events like signups to the web analytics tool (like kissmetrics) and javascript syntax would be _ga.push(['register', event, extra_data])

The challenge is that in you tests you can't run it from your application as it will share user session and it wouldn't test same origin policy.

Tools stack: Capybara, Webkit, Rspec, Sinatra

So the solution is to have a separate application which will act as a dummy client. I've chose sinatra as it fits perfectly for that role. One of the cool features that rack has is its ability to mount other rack applications inside it. So in run_dummy_client helper we mount sinatra application to /dummy_client path.

But that's not all. In order for this to work we need to run dummy client from different domain. That could be easily done through modifying etc/hosts file or having a proxy which will redirect custom local domain to specific host (that can be done with POW.cx). And at the end don't forget to move that configuration setup into a rake task so you do don't need to remember it next time.

So after the setup is complete we can create helper method with similar syntax as javascript ga_push which will take any number of arguments and will call javascript _ga.push with exactly the same arguments. With such setup we can easily expand our integration tests with a more sophisticated use cases.

client_script_spec.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
require 'spec_helper'
 
describe "client_script.js" do
 
before :all do
run_dummy_client
end
 
before :each do
Capybara.current_driver = :webkit
end
 
describe '#register' do
it "tracks new sign-ups" do
visit dummy_client_url
 
expect {
ga_push 'register', 'signup', {
name: "new user",
email: 'new_user@email.com',
customer_id: '101'
}
}.to change(Customer, 'count').by(1)
 
end
end
end
dummy_client.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
require 'sinatra/base'
 
def dummy_client_url options = {}
"http://test.app.dev/dummy_client/?#{options.to_query}"
end
 
def ga_push *args
page.execute_script "_ga.push( #{args.to_json} );"
end
 
# This spec needs domains to be setup correctly.
# Don't forget to run 'rake dev:domains' to setup POW domains.
def run_dummy_client
Capybara.server_port = 31337
Capybara.app = Rack::Builder.new do
map "/dummy_client" do
run dummy_client_app
end
 
map "/" do
run App::Application
end
end.to_app
end
 
def dummy_client_app
Sinatra.new do
get '/' do
<<-END
<!DOCTYPE html>
<html lang="en">
<head>
<script src='/assets/jquery-1.8.1.min.js'></script>
<script src="http://test.app.dev/assets/client_script.js"></script>
</head>
<body></body>
</html>
END
end
end
 
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.