Browsers are enablers. They look at your mangled nightmare of a document, quietly fix it behind your back, and render something that looks close enough. Not a word of complaint. Which is exactly why invalid HTML tends to hide real bugs: forms that silently bin your users' data, nesting so broken it looks fine in Chrome but implodes in Safari, unclosed tags that swallow entire sections on mobile. If your markup doesn't validate, something is wrong, and you really want to find that out in your test suite, not when a customer emails you a screenshot at 2am.
In the Rails world, the
be_valid_asset
gem does the right thing here: it ships your rendered
markup off to the official W3C validator and fails your
spec if it comes back dodgy. Brilliant idea, one tiny
problem: it depends
on a live internet connection to a remote service you
do not control. So you're on a train, or a coffee
shop with Wi-Fi held together by prayers, or a plane
where the internet costs twelve dollars and doesn't
actually work, and suddenly your entire test suite is
red for reasons that have absolutely nothing to do with
your code. Lovely.
Now, the W3C Validator Service can be installed locally, but getting it running natively on macOS is the kind of afternoon you don't get back. Docker, on the other hand, makes it stupidly easy.
Running the validator in Docker
Peter Mescalchin, absolute legend, has already done the hard work and packaged the whole thing into a ready-made html5validator Docker container. Just fire it up with a port forward so your test suite can talk to it:
$ docker run -d -p 8888:80 magnetikonline/html5validator
That pulls the image (first time only, relax), starts
the container in the background, and maps port 8888 on
your machine to the Apache service inside. Once it's
up, open http://localhost:8888 in your
browser and bask in the glory of a W3C validator that
lives on your own bloody laptop. The API endpoint you
actually care about is at the /check path:
http://localhost:8888/check
Configure BeValidAsset to use the local container
Here's the beautiful part: be_valid_asset
already accepts a custom validator host, so pointing
it at your shiny local container is literally one line
of configuration. One. Line.
# in spec/support/be_valid_asset.rb
BeValidAsset::Configuration.markup_validator_host = 'http://192.168.99.100:32770'
If you want to get fancy with more configuration, knock yourself out and check the README.
- Run the W3C validator locally with
docker run -d -p 8888:80 magnetikonline/html5validator - Point
be_valid_assetatlocalhost:8888to remove the internet dependency from your test suite - Your tests should never break because of someone else's server
Full disclosure, because I'm not a monster:
be_valid_asset was built by yours truly
and my colleagues at
Unboxed.
The Docker container was built by Peter Mescalchin
(@magnetikonline),
who saved us all from a very boring afternoon.