UIAutomation and Pusher

UIAutomation is Apple’s answer to integration tests. It allows you to drive and run assertions against your application using a javascript library that interacts with user interface elements. It’s great to have such a powerful tool, but what if you have an application that depends on external triggers, such as Pusher events?

Let me introduce you to UIAHost. More specifically, it’s method performTaskWithPathArgumentsTimeout. What this allows you to do is execute a script in the flow of your tests.

Say we want to execute the ruby script:

#!/usr/bin/env ruby
require "pusher"
channel = ARGV[0]
event = ARGV[1]
data = ARGV[2]
Pusher[channel].trigger(event, data)

All we have to do in our UIAutomation script is this:

var host = UIATarget.localTarget().host();
var timeout = 5; // seconds
var args = ['test_channel', 'test-event', '{"hello":"world"}'];
var scriptPath = "/Users/home/me/pusher_script";
var result = host.performTaskWithPathArgumentsTimeout(scriptPath,args,timeout);

That’s a pretty simple ruby script, and will fail to find the pusher gem on any of our machines at Bendyworks because we use RVM. So what we need to do is load RVM into the environment (explained further here):

#!/usr/bin/env bash
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
  source "$HOME/.rvm/scripts/rvm"
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
  source "/usr/local/rvm/scripts/rvm"
else
  printf "ERROR: An RVM installation was not found.\n"
fi

RVM is loaded, now we can set the gemset like so:

rvm use [email protected]

Now our simple ruby script has evolved into a bash script in order to load the correct ruby environment and our gemset along with it. Now how are we going to execute a ruby script with it? Well, we could assign our ruby into a bash variable then run it with ruby -e like so:

ruby_script=$(cat <<EOP
require "pusher"
Pusher['test_channel'].trigger('hello_event', {hello: 'world'})
EOP)
ruby -e "$ruby_script"

Wonderful! Now we can trigger a pusher event from our automation code and then assert that our app does what it’s supposed to.

Here is the script in all its glory:

#!/usr/bin/env bash

if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
  source "$HOME/.rvm/scripts/rvm"
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
  source "/usr/local/rvm/scripts/rvm"
else
  printf "ERROR: An RVM installation was not found.\n"
fi

rvm use [email protected]

ruby_program=$(cat <<EOP
require 'pusher'

Pusher.app_id = '<your_app_id>'
Pusher.key = '<your_app_key>'
Pusher.secret = '<your_pusher_secret>'

channel = %Q($1)
event = %Q($2)
data = %Q($3)

if channel &#038;&#038; event &#038;&#038; data
  Pusher[channel].trigger(event, data)
else
  puts 'usage: pusher_event <channel> <event> <data>'
end
EOP
)
ruby -e "$ruby_program"

Category: Development
Tags: Tutorial