A fully-automated testing rig #4
Nathan Page
##Part 4: When TrueType doesn't fix everything
#####Two fonts walk into the bar, and the barman says, “Sorry lads, we don’t serve your type.”
It was a good day. I'd finished writing up the basic appearance tests for the first batch of content types, I'd road-tested them on my machine, we'd set up Jenkins… all was ready to go for our first run on the server. When we ran it, however, all the tests failed against the baseline.
Every single one.
Things started to get tense as it became clear that the solution was no trivial matter: we were experiencing several very interesting things…
-
The fonts weren't installed on our server. It's easy to forget that your Linux server might not have all your fonts installed, but fortunately it's not too difficult to fix if you have the necessary access and permissions.
-
Antialiasing is an OS-specific operation. Even we had the right fonts, the tests were still failing, and we were left asking "why do the fonts look different?!". They were being 'displayed' (this is a headless browser, don't forget, but they're still rendered) differently on the Linux system to our MacOS office systems.
The heart of the matter comes down to aliasing, the smoothing of fonts for display. It's what makes them always look so nice, whatever screen they're on; read up here. This is normally performed by the operating system, rather than the browser, so the only way to standardise the appearance of the fonts.
As you'd hope would be the case, Webkit does allow you to specify the aliasing method you want to be applied. Since we only needed the aliasing to change for the testing process, it wouldn't be worth inserting anything into the actual site. jQuery to the rescue! We put the following in our pre script. It adds an event, so that whenever a page finishes loading, the page has the necessary CSS injected before we start trying to do anything important:
# Use jQuery to inject CSS, standardising the tests against OS-specific text smoothing/aliasing methods
casper.on "load.finished", ->
this.evaluate ->
s = document.createElement('style')
s.type = 'text/css' s.innerText = '* {-webkit-font-smoothing: none !important}'
document.querySelector('head').appendChild(s)
With all this in place the fonts finally rendered identically on the server as on our office machines. Still, just in case, we only ever render new baseline images from the server.