Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
78 lines (52 sloc) 2.87 KB
---
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