Permalink
Cannot retrieve contributors at this time
--- | |
title: Store screenshots of your web app in Git | |
date: "2013-08-23 18:22 CEST" | |
tags: testing, git, phantomjs, ruby | |
published: true | |
--- | |
<iframe style='max-width:100%' width="600" height="340" src="//www.youtube.com/embed/VMhdKZDxFjg" frameborder="0" allowfullscreen></iframe> | |
Have you ever had a change break your site? Even when the tests pass? | |
* Testing functionality is hard | |
* Testing UI is even harder | |
What if every time you commit, you got a visual diff of every web page that changed? | |
It is surprisingly easy to do. | |
<%= article_image_tag 'gh-img-diff-1.png', class: 'img-fluid'%> | |
READMORE | |
### How? | |
All we need is a headless browser and a testing environment. | |
For Rails you can use poltergeist + rspec and [just][rep-helper] do [this][rep-spec] like in the tests for my [Rails Email Preview][rep] gem. You then simply list the shots you want: | |
~~~ ruby | |
describe 'Take screenshots', driver: :poltergeist do | |
it 'home page' do | |
visit '/' | |
screenshot! 'home' | |
end | |
it 'user account page' do | |
sign_in Fabricate(:user) | |
visit my_account_url | |
screenshot! 'my-account' | |
end | |
end | |
~~~ | |
The code will simply place screenshots into `spec/screenshots` each time the test suite is run. | |
Once you add `spec/screenshots` to git, things get interesting. | |
### Perks unlocked | |
With your screenshots under version control, you will | |
* Always know when you introduce a change that changes the display | |
* See which commits changed screens in your app | |
* Instantly see what your app looked like at any point in time | |
You must use `git submodule add {separate repo URL} spec/screenshots` to keep screenshots in a separate repo, as it will get large. | |
You can also script rewriting images out of older commits via `git filter-branch` if repo grows too large. | |
Below is an image diff as [rendered by Github][rep-commit]. This is *visual version history* and your private *git wayback machine*. | |
[<%= article_image_tag 'gh-img-diff-2.png', class: 'img-fluid' %>][rep-commit] | |
I hope this post has helped you. Please let me know if you already do this, as I'm curious to hear other approaches. | |
-- [@glebm][glebm-twtr] | |
*Thanks [@ddtrejo](https://twitter.com/ddtrejo) for your edits and suggestions!* | |
#### See also | |
* [Discussion on Hacker News](https://news.ycombinator.com/item?id=6266490) - some nice ideas around this approach. | |
* [Huxley](https://github.com/facebook/huxley/) - implementation of screenshot control in Selenium and written in Python. *Thanks [@petehunt](https://github.com/petehunt)* | |
[rep]: https://github.com/glebm/rails_email_preview | |
[rep-spec]: https://github.com/glebm/rails_email_preview/blob/master/spec/features/take_screenshots_spec.rb | |
[rep-helper]: https://github.com/glebm/rails_email_preview/blob/master/spec/support/save_screenshots.rb | |
[rep-commit]: https://github.com/glebm/rails_email_preview/commit/b6b003bf3a49ecf36d51ecf39dcd57e42e259dad?&diff-1=1-82#L14R3 | |
[glebm-twtr]: https://twitter.com/glebm | |