Computers aren’t very good at testing visual changes on websites. Sure you can test the differences between two images, but image changes are really brittle. However, humans are pretty good at it. As a result, the common way to test visuals it to actually click through stuff on a browser. This doesn’t scale. For one, if your UI changes based on different initial states, it can take ages to set this stuff up.
Thankfully there is a fairly simple solution.
Aside: There is another solution: Using something like BrowserStack, although because it works remotely, it might make setting up the testing environment between tests difficult. I’ll look at this later in another blog post once I get a chance to play with it.
There are pros and cons to both systems:
Pro: Can control basically any browser that it has a driver for – including Android and iPhones.
Con: It requires Java and a computer with all of those browsers and emulators installed. It’s also the slower of the two.
Pro: Is headless, so doesn’t require X windows, or any other window manager.
Con: It’s WebKit only.
I’ll go through setting up PhantomJS on OSX, because that’s what I’ve set up so far; I’ll leave setting up Selenium as an exercise for the reader – the theory should be the same.
First, you need to install PhantomJS. On OSX, it’s just a matter of using homebrew
brew install phantomjs
Next, add the poltergeist gem (which is an interface to PhantomJS. It will also install Capybara)
group :test do gem "poltergeist", "~> 1.3.0" end
Add the following to your test/test_helper.js
Finally, generate a integration test
rails generate integration_test name_of_the_test
Open up the Integration test and create a test
require 'test_helper' class NameOfTheTestIntegrationTest < ActionDispatch::IntegrationTest # Don't forget this line - Database transactions don't work well with Capybara self.use_transactional_fixtures = false test 'some test name' do visit '/' # This is the important line. This is what saves the screenshot save_screenshot(Rails.root.join('tmp', 'screenshots', 'name_of_the_integration', 'some-test-name.png')) end end
Run the integration test, and you will find a nice 1024×768 PNG screen shot in the tmp/screenshots/name_of_the_integration/some-test-name.png directory.
So, after your tests run, you can scan through the screen shots and see if anything looks weird. Win!
For a more in-depth instructions for running tests in Capybara, checkout their GitHub page.