Running PhantomJS Ghost Driver as an OS X service

Recently, I have been experimenting with the Phoenix Framework and testing tool called Hound. Hound allows you to write integration tests that drive your app with a headless PhantomJS browser. However, in order to use PhantomJS with Hound you must have a Ghost Driver session running on your Mac.

Manually Running Ghost Driver

Ghost Driver comes bundled with PhantomJS, and can be installed on OS X using Homebrew:

$ brew install phantomjs

After that, running a Ghost Driver session is just a single command.

$ phantomjs --wd

Your tests will pass now, but you have to remember to run this command and keep it running while your working on your app.

Letting launchd take care of it

I figured there had to be an easier way to automatically start Ghost Driver. Then I remembered all those .plist files that Homebrew tells you to link to ~/Library/LaunchAgents if you want services to start automatically.

After a little experimentation, I created my own LaunchAgent file and stored it in ~/Library/LaunchAgents/org.phantomjs.ghostdriver.plist.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.phantomjs.ghostdriver</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/usr/local/opt/phantomjs/bin/phantomjs</string>
<string>--wd</string>
</array>
<key>StandardErrorPath</key>
<string>/usr/local/var/log/phantomjs-ghostdriver-error.log</string>
<key>StandardOutPath</key>
<string>/usr/local/var/log/phantomjs-ghostdriver-output.log</string>
</dict>
</plist>

Now I can manually start Ghost Driver with my new script:

$ launchctl load ~/Library/LaunchAgents/org.phantomjs.ghostdriver.plist

If I need to stop it, I can run the following:

$ launchctl unload ~/Library/LaunchAgents/org.phantomjs.ghostdriver.plist

The great part about using launchctl is it will launch this agent every time I start my computer. It a "set it and forget it" script, that will make sure my tests won't fail just because Ghost Driver isn't started.

Other notes

When working with launchctl, make sure you are not running in a tmux session. Homebrew warns you about this as part of many installation scripts and it still applies here.

If you have any other comments or suggestions, feel free to hit me up on Twitter.


Originally published at blog.animascodelabs.com on December 31, 2015.