Using PhantomJS with django for d3 testing

I’ve been working with phantomjs recently. It’s a javascript based system wrapper around a webkit backend. This allows one to make requests against a website and run the client side javascript, and make screenshots of the way the webpage would be generated including all css.

I’m using it to generate d3 graphs for testings whereby images of the webpage as saved and compared to expected images.

Of course I’m using python since my websites are all in python and usually django these days. So calling a javascript command and pointing it at a running webserver sounds like a really hard task. But actually django provides a live TestCase which runs a test web server which phantomjs can use as it’s source. It even includes fixtures and other test features which makes it fairly easy to put together the basics of what’s needed.

import logging
from subprocess import Popen, PIPE
from django.test import LiveServerTestCase

class GraphTestCase(LiveServerTestCase):
# Tests and fixtures go here as well as login via self.client (as usual)

def phantom(self, filename, **kwargs):
"""Run a phantomjs script and return True if it was successful"""
pre_args = []

# These cookies require the target js to support them.
cn = settings.SESSION_COOKIE_NAME
if cn in self.client.cookies:
kwargs['cookie-' + cn] = self.client.cookies[cn].value

args = ['--%s=%s' % item for item in kwargs.items()]
cmd = [self.script] + pre_args + [self.get_js_file(filename)] + args

process = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True)
out, err = process.communicate()
if process.returncode != 0:
logging.info(out)
logging.error(err)
raise IOError("Process did not complete: %d" % process.returncode)
return out

The above code should be well formatted, but wordpress (or this version of it) doesn’t want to use the right tags for code. :-/