selfie 0.0.1.pre → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: db69321a35c40a000ef02d5d9c485fa4e058c45d
4
- data.tar.gz: 725d7e2526a7d0f227d17fc6c338d99f3560f5ca
3
+ metadata.gz: 6bc05951c6292fdc8b8a6b66d19de4ef2e264058
4
+ data.tar.gz: 9766f95411f54e665e4b0b50646adb3949482f5a
5
5
  SHA512:
6
- metadata.gz: fae0a01191b8f843521e3f3dba110ac54c5e1e85b28bbb506b6ef2aead7e896301e813722dab21c4c6b3d3e6b3bd685e80acdf3d7e4c63f1f90328045f13eb38
7
- data.tar.gz: 0b38e9f83756754f6856a00e9c08c6ea9980b7dcc9458892166aa4cf4e181e7bafba5d9649331c31510b4fe27ee96d13f8e8313573b99cf4a230e8982e4e420c
6
+ metadata.gz: dbbbb0e68288151ec1c2ec21d9cb60e1eaa8facc7fa5dad01f0cd2823356c42e828d27bbab95a80c6357286cc853ad70c92b8833003a2b461e16dd7a42abe21a
7
+ data.tar.gz: c4ddced49ff082facdf39aafa3ca4918fe58d39a50ae102e12c128a629bae102b644636eb77449895a92f97bc5af89b12042f0c893b8cf8e86d34c6b1a86f280
data/README.md CHANGED
@@ -1 +1,93 @@
1
- # Selfie
1
+ # Selfie
2
+
3
+ Visual UI regression tests using PhantomJS, Poltergeist and Imagemagick for Capybara.
4
+
5
+ ## To get started
6
+
7
+ For rails it's easy! Just add ``selfie`` to your ``Gemfile``
8
+
9
+ ```
10
+ gem 'selfie'
11
+ ```
12
+
13
+ Then create an integration test and include the `Selfie::DSL` and use `snap!` to capture a screenshot.
14
+
15
+ ```
16
+ class CompletePurchaseTest < ActiveSupport::TestCase
17
+ include Capybara::DSL
18
+ include Selfie::DSL
19
+
20
+ test "should do a complete purchase" do
21
+ visit '/'
22
+ assert has_content? 'Welcome to Shopping!'
23
+
24
+ snap! 'home'
25
+
26
+ # do more stuff here.
27
+
28
+ make_report
29
+ open_report
30
+ end
31
+ end
32
+ ```
33
+ ### Creating reference image sets
34
+
35
+ Easy huh, except there is at this moment nothing to diff with. You need to run
36
+ the script once to create your reference images.
37
+
38
+ Selfie saves the images of the current run into `tmp/snap/current`. You can simply copy
39
+ that directory to create your reference images. It will look for the reference images in th `test/assets` directory. The name of the directory is the underscored variant with ``Test`` removed so in this case ``complete_purchase``
40
+
41
+ ```
42
+ cp -R tmp/snap/current test/assets/complete_purchase
43
+ ```
44
+
45
+
46
+ ## Being forgiving
47
+
48
+ Sometimes you don't want a single pixel to fail your test. For instance, when you work
49
+ with generated dates. You can provide a threshold that allows for changes:
50
+
51
+ ```
52
+ snap! 'home', threshold: 0.01
53
+ ```
54
+
55
+ You can see the threshold next to the image result in the make report.
56
+
57
+ ## Capturing page on failed asserts
58
+
59
+ If you want to capture an image on a failed assert you can use the following 'freedom-patch' to override `assert`.
60
+
61
+ Like this:
62
+
63
+ ```
64
+ class PurchaseTest < ActiveSupport::TestCase
65
+ def assert(*args)
66
+ passed = super(*args)
67
+ ensure
68
+ snap 'ERROR!' unless passed
69
+ end
70
+ end
71
+ ```
72
+
73
+ ## Being async
74
+
75
+ `snap!` doesn't wait for a page load, it just snaps te current page. Normally, you might want to use one of the Capybara ``finders``, such as
76
+
77
+ ```
78
+ assert has_content? 'Welcome to Shopping!'
79
+ ```
80
+ to verify that specific page has loaded before you snap a shot!
81
+
82
+ ## Under the hood
83
+
84
+ It basically relies on a couple of components. PhantomJS, and ImageMagick. It uses PhantomJS's, `save_screenshot` method to capture a screenshot. And ImageMagic's ``compare`` and ``convert`` to make a diff and measure the difference.
85
+
86
+ ## Contribute!
87
+
88
+ Awesome please help me out! This is cool, but it can be much cooler, friendlier. More awesome. A couple of things on my wishlist!
89
+
90
+ - A assert `snap_and_compare! 'home', threshold: 0.05`
91
+ - snap! with a given element
92
+ - Add some tests if you like
93
+
data/lib/selfie/dsl.rb ADDED
@@ -0,0 +1,139 @@
1
+ module Selfie
2
+ module DSL
3
+ def snap_reference_dir
4
+ asset = self.class.name.gsub(/Test$/,'').underscore
5
+ asset_dir = File.join 'test','assets', asset
6
+ end
7
+
8
+ def make_report
9
+ process_images
10
+ File.write("snap.html", ERB.new(template).result(binding))
11
+ end
12
+
13
+ def open_report
14
+ `open snap.html`
15
+ end
16
+
17
+ def process_images
18
+ @diff = []
19
+ @has_diff = Dir.exist? snap_reference_dir
20
+
21
+ for snap in @snaps
22
+ name = snap[:name]
23
+ snap[:src] = src = "tmp/snap/current/#{name}.png"
24
+
25
+ next unless @has_diff
26
+
27
+ snap[:diff] = diff = "tmp/snap/current/#{name}_diff.png"
28
+ snap[:ref] = ref = "#{snap_reference_dir}/#{name}.png"
29
+
30
+ `compare #{ref} #{src} #{diff}`
31
+ cmd = "convert #{ref} #{src} -compose Difference -composite -colorspace gray -format '%[fx:mean*100]' info:"
32
+
33
+ snap[:psr] = (`#{cmd}`).strip.to_f
34
+ snap[:changed] = snap[:psr] > snap[:threshold]
35
+
36
+ @diff << snap if snap[:changed]
37
+ end
38
+ end
39
+
40
+ def snap!(name, options={})
41
+
42
+ name = ("%03d" % @film += 1) + "_#{name}"
43
+ path = "tmp/snap/current/#{name}.png"
44
+
45
+ snap = {name: name, url: current_url}
46
+ snap[:threshold] = 0
47
+
48
+ snap.merge!(options)
49
+
50
+ @snaps << snap
51
+ save_screenshot(path, :full => true)
52
+ end
53
+
54
+ def setup_selfie
55
+ @snaps = []
56
+ @film = 0
57
+ `rm -rf tmp/snap/current`
58
+ `mkdir -p tmp/snap/current`
59
+ end
60
+
61
+ def template
62
+ <<-ERB
63
+
64
+ <style>
65
+ body {
66
+ color:#4a4a4a;
67
+ background-color:#efefef;
68
+ }
69
+ .paper {
70
+ border:1px solid #d0d0d0;
71
+ font-family:helvetica;
72
+ padding:20px;
73
+ width:1500px;
74
+ margin:50px auto; border:1px solid #efefef;
75
+ border-radius:10px;
76
+ background-color:white;
77
+ }
78
+ .no-ref {
79
+ background-color:#efeeef;padding:10px; border-radius:5px;
80
+ }
81
+ p {
82
+ word-wrap: break-word;
83
+ }
84
+ hr {
85
+ border-color:#d0d0d0
86
+ }
87
+ .results img { border:10px solid #efefef; width:720px; }
88
+ .failed { color:#FF9999; }
89
+ .img-failed img { border-color:#FF9999;}
90
+ .logo {float:right;width:80px; border-radius:5px;width:60px;height:60px}
91
+ </style>
92
+
93
+ <title>Selfie results</title>
94
+ <body>
95
+ <div class='paper'>
96
+ <img class='logo' title='Emile <3 you!' src='https://0.gravatar.com/avatar/aca8aad5245e144c9222102decb1776e&s=440'/>
97
+
98
+ <h1 class='<%=(@diff.empty? ? "success" : "failed") %>'>Selfie - <%=(@diff.empty? ? "Lookin' good :)" : "Things changed") %></h1>
99
+
100
+ <hr size=1/>
101
+
102
+ <% unless @has_diff %>
103
+ <div class='no-ref'>No reference images path defined in '<%=snap_reference_dir%>' -
104
+ You can copy this: 'cp -R tmp/snap/current <%=snap_reference_dir%>'
105
+ </div>
106
+ <% end %>
107
+
108
+ <div class='results'>
109
+ <% unless @diff.empty? %>
110
+ <h2>These <%=@diff.length%> snaps are different</h2>
111
+ <% for snap in @diff %>
112
+ <div class='<%=(snap[:changed] ? "img-failed" : "img-success")%>'>
113
+ <h3><%=snap[:name]%> (<%=snap[:psr]%>)</h3>
114
+ <p><%=snap[:url]%></p>
115
+ <p><%=snap[:note]%></p>
116
+ <a href='<%=snap[:src]%>'><img src='<%=snap[:src]%>'/ ></a>
117
+ <a href='<%=snap[:diff]%>'><img src='<%=snap[:diff]%>'/ ></a>
118
+ </div>
119
+ <% end %>
120
+ <hr size=1/>
121
+ <% end %>
122
+
123
+ <h2>All snaps</h2>
124
+ <% for snap in @snaps %>
125
+ <div class='<%=(snap[:changed] ? "img-failed" : "img-success")%>'>
126
+ <h3><%=snap[:name]%> (<%=snap[:psr]%>)</h3>
127
+ <p><%=snap[:url]%></p>
128
+ <p><%=snap[:note]%></p>
129
+ <a href='<%=snap[:src]%>'><img src='<%=snap[:src]%>'/ ></a>
130
+ <a href='<%=snap[:diff]%>'><img src='<%=snap[:diff]%>'/ ></a>
131
+ </div>
132
+ <% end %>
133
+ </div>
134
+ </div>
135
+ </body>
136
+ ERB
137
+ end
138
+ end
139
+ end
@@ -1,3 +1,3 @@
1
1
  module Selfie
2
- VERSION = '0.0.1.pre'
2
+ VERSION = '0.0.1'
3
3
  end
data/lib/selfie.rb CHANGED
@@ -1 +1,2 @@
1
- require 'selfie/version'
1
+ require 'selfie/version'
2
+ require 'selfie/dsl'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selfie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emile Bosch
@@ -9,7 +9,35 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2013-10-24 00:00:00.000000000 Z
12
- dependencies: []
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: simplecov
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: poltergeist
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  description: Selfie takes screenshots of itself, when running your poltergeist tests,
14
42
  little egotistical bastard.
15
43
  email: emilebosch@me.com
@@ -17,11 +45,10 @@ executables: []
17
45
  extensions: []
18
46
  extra_rdoc_files: []
19
47
  files:
48
+ - lib/selfie/dsl.rb
20
49
  - lib/selfie/version.rb
21
50
  - lib/selfie.rb
22
51
  - README.md
23
- - selfie.gemspec
24
- - Gemfile
25
52
  homepage: https://github.com/emilebosch/selfie
26
53
  licenses:
27
54
  - MIT
@@ -37,14 +64,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
37
64
  version: '0'
38
65
  required_rubygems_version: !ruby/object:Gem::Requirement
39
66
  requirements:
40
- - - '>'
67
+ - - '>='
41
68
  - !ruby/object:Gem::Version
42
- version: 1.3.1
69
+ version: '0'
43
70
  requirements: []
44
71
  rubyforge_project:
45
72
  rubygems_version: 2.0.2
46
73
  signing_key:
47
74
  specification_version: 4
48
- summary: Screenshots for your poltegergeist tests
75
+ summary: Screenshots for your poltergeist tests
49
76
  test_files: []
50
77
  has_rdoc:
data/Gemfile DELETED
@@ -1,2 +0,0 @@
1
- source "https://rubygems.org"
2
- gemspec
data/selfie.gemspec DELETED
@@ -1,14 +0,0 @@
1
- require './lib/selfie/version'
2
-
3
- Gem::Specification.new do |s|
4
- s.name = 'selfie'
5
- s.version = Selfie::VERSION
6
- s.date = '2013-10-24'
7
- s.summary = "Screenshots for your poltegergeist tests"
8
- s.description = "Selfie takes screenshots of itself, when running your poltergeist tests, little egotistical bastard."
9
- s.authors = ["Emile Bosch"]
10
- s.email = 'emilebosch@me.com'
11
- s.files = Dir.glob('{lib}/**/*') + %w(README.md selfie.gemspec Gemfile)
12
- s.homepage = 'https://github.com/emilebosch/selfie'
13
- s.license = 'MIT'
14
- end