looks_good 1.0.0

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.
@@ -0,0 +1,340 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <title>RSpec results</title>
8
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
9
+ <meta http-equiv="Expires" content="-1" />
10
+ <meta http-equiv="Pragma" content="no-cache" />
11
+ <style type="text/css">
12
+ body {
13
+ margin: 0;
14
+ padding: 0;
15
+ background: #fff;
16
+ font-size: 80%;
17
+ }
18
+ </style>
19
+ <script type="text/javascript">
20
+ // <![CDATA[
21
+
22
+ function addClass(element_id, classname) {
23
+ document.getElementById(element_id).className += (" " + classname);
24
+ }
25
+
26
+ function removeClass(element_id, classname) {
27
+ var elem = document.getElementById(element_id);
28
+ var classlist = elem.className.replace(classname,'');
29
+ elem.className = classlist;
30
+ }
31
+
32
+ function moveProgressBar(percentDone) {
33
+ document.getElementById("rspec-header").style.width = percentDone +"%";
34
+ }
35
+
36
+ function makeRed(element_id) {
37
+ removeClass(element_id, 'passed');
38
+ removeClass(element_id, 'not_implemented');
39
+ addClass(element_id,'failed');
40
+ }
41
+
42
+ function makeYellow(element_id) {
43
+ var elem = document.getElementById(element_id);
44
+ if (elem.className.indexOf("failed") == -1) { // class doesn't includes failed
45
+ if (elem.className.indexOf("not_implemented") == -1) { // class doesn't include not_implemented
46
+ removeClass(element_id, 'passed');
47
+ addClass(element_id,'not_implemented');
48
+ }
49
+ }
50
+ }
51
+
52
+ function apply_filters() {
53
+ var passed_filter = document.getElementById('passed_checkbox').checked;
54
+ var failed_filter = document.getElementById('failed_checkbox').checked;
55
+ var pending_filter = document.getElementById('pending_checkbox').checked;
56
+
57
+ assign_display_style("example passed", passed_filter);
58
+ assign_display_style("example failed", failed_filter);
59
+ assign_display_style("example not_implemented", pending_filter);
60
+
61
+ assign_display_style_for_group("example_group passed", passed_filter);
62
+ assign_display_style_for_group("example_group not_implemented", pending_filter, pending_filter || passed_filter);
63
+ assign_display_style_for_group("example_group failed", failed_filter, failed_filter || pending_filter || passed_filter);
64
+ }
65
+
66
+ function get_display_style(display_flag) {
67
+ var style_mode = 'none';
68
+ if (display_flag == true) {
69
+ style_mode = 'block';
70
+ }
71
+ return style_mode;
72
+ }
73
+
74
+ function assign_display_style(classname, display_flag) {
75
+ var style_mode = get_display_style(display_flag);
76
+ var elems = document.getElementsByClassName(classname)
77
+ for (var i=0; i<elems.length;i++) {
78
+ elems[i].style.display = style_mode;
79
+ }
80
+ }
81
+
82
+ function assign_display_style_for_group(classname, display_flag, subgroup_flag) {
83
+ var display_style_mode = get_display_style(display_flag);
84
+ var subgroup_style_mode = get_display_style(subgroup_flag);
85
+ var elems = document.getElementsByClassName(classname)
86
+ for (var i=0; i<elems.length;i++) {
87
+ var style_mode = display_style_mode;
88
+ if ((display_flag != subgroup_flag) && (elems[i].getElementsByTagName('dt')[0].innerHTML.indexOf(", ") != -1)) {
89
+ elems[i].style.display = subgroup_style_mode;
90
+ } else {
91
+ elems[i].style.display = display_style_mode;
92
+ }
93
+ }
94
+ }
95
+
96
+ // ]]>
97
+ </script>
98
+ <style type="text/css">
99
+ #rspec-header {
100
+ background: #65C400; color: #fff; height: 4em;
101
+ }
102
+
103
+ .rspec-report h1 {
104
+ margin: 0px 10px 0px 10px;
105
+ padding: 10px;
106
+ font-family: "Lucida Grande", Helvetica, sans-serif;
107
+ font-size: 1.8em;
108
+ position: absolute;
109
+ }
110
+
111
+ #label {
112
+ float:left;
113
+ }
114
+
115
+ #display-filters {
116
+ float:left;
117
+ padding: 28px 0 0 40%;
118
+ font-family: "Lucida Grande", Helvetica, sans-serif;
119
+ }
120
+
121
+ #summary {
122
+ float:right;
123
+ padding: 5px 10px;
124
+ font-family: "Lucida Grande", Helvetica, sans-serif;
125
+ text-align: right;
126
+ }
127
+
128
+ #summary p {
129
+ margin: 0 0 0 2px;
130
+ }
131
+
132
+ #summary #totals {
133
+ font-size: 1.2em;
134
+ }
135
+
136
+ .example_group {
137
+ margin: 0 10px 5px;
138
+ background: #fff;
139
+ }
140
+
141
+ dl {
142
+ margin: 0; padding: 0 0 5px;
143
+ font: normal 11px "Lucida Grande", Helvetica, sans-serif;
144
+ }
145
+
146
+ dt {
147
+ padding: 3px;
148
+ background: #65C400;
149
+ color: #fff;
150
+ font-weight: bold;
151
+ }
152
+
153
+ dd {
154
+ margin: 5px 0 5px 5px;
155
+ padding: 3px 3px 3px 18px;
156
+ }
157
+
158
+
159
+ dd.example.passed {
160
+ border-left: 5px solid #65C400;
161
+ border-bottom: 1px solid #65C400;
162
+ background: #DBFFB4; color: #3D7700;
163
+ }
164
+
165
+ dd.example.not_implemented {
166
+ border-left: 5px solid #FAF834;
167
+ border-bottom: 1px solid #FAF834;
168
+ background: #FCFB98; color: #131313;
169
+ }
170
+
171
+ dd.example.pending_fixed {
172
+ border-left: 5px solid #0000C2;
173
+ border-bottom: 1px solid #0000C2;
174
+ color: #0000C2; background: #D3FBFF;
175
+ }
176
+
177
+ dd.example.failed {
178
+ border-left: 5px solid #C20000;
179
+ border-bottom: 1px solid #C20000;
180
+ color: #C20000; background: #FFFBD3;
181
+ }
182
+
183
+
184
+ dt.not_implemented {
185
+ color: #000000; background: #FAF834;
186
+ }
187
+
188
+ dt.pending_fixed {
189
+ color: #FFFFFF; background: #C40D0D;
190
+ }
191
+
192
+ dt.failed {
193
+ color: #FFFFFF; background: #C40D0D;
194
+ }
195
+
196
+
197
+ #rspec-header.not_implemented {
198
+ color: #000000; background: #FAF834;
199
+ }
200
+
201
+ #rspec-header.pending_fixed {
202
+ color: #FFFFFF; background: #C40D0D;
203
+ }
204
+
205
+ #rspec-header.failed {
206
+ color: #FFFFFF; background: #C40D0D;
207
+ }
208
+
209
+
210
+ .backtrace {
211
+ color: #000;
212
+ font-size: 12px;
213
+ }
214
+
215
+ a {
216
+ color: #BE5C00;
217
+ }
218
+
219
+ /* Ruby code, style similar to vibrant ink */
220
+ .ruby {
221
+ font-size: 12px;
222
+ font-family: monospace;
223
+ color: white;
224
+ background-color: black;
225
+ padding: 0.1em 0 0.2em 0;
226
+ }
227
+
228
+ .ruby .keyword { color: #FF6600; }
229
+ .ruby .constant { color: #339999; }
230
+ .ruby .attribute { color: white; }
231
+ .ruby .global { color: white; }
232
+ .ruby .module { color: white; }
233
+ .ruby .class { color: white; }
234
+ .ruby .string { color: #66FF00; }
235
+ .ruby .ident { color: white; }
236
+ .ruby .method { color: #FFCC00; }
237
+ .ruby .number { color: white; }
238
+ .ruby .char { color: white; }
239
+ .ruby .comment { color: #9933CC; }
240
+ .ruby .symbol { color: white; }
241
+ .ruby .regex { color: #44B4CC; }
242
+ .ruby .punct { color: white; }
243
+ .ruby .escape { color: white; }
244
+ .ruby .interp { color: white; }
245
+ .ruby .expr { color: white; }
246
+
247
+ .ruby .offending { background-color: gray; }
248
+ .ruby .linenum {
249
+ width: 75px;
250
+ padding: 0.1em 1em 0.2em 0;
251
+ color: #000000;
252
+ background-color: #FFFBD3;
253
+ }
254
+
255
+ </style>
256
+ </head>
257
+ <body>
258
+ <div class="rspec-report">
259
+
260
+ <div id="rspec-header">
261
+ <div id="label">
262
+ <h1>RSpec Code Examples</h1>
263
+ </div>
264
+
265
+ <div id="display-filters">
266
+ <input id="passed_checkbox" name="passed_checkbox" type="checkbox" checked onchange="apply_filters()" value="1"> <label for="passed_checkbox">Passed</label>
267
+ <input id="failed_checkbox" name="failed_checkbox" type="checkbox" checked onchange="apply_filters()" value="2"> <label for="failed_checkbox">Failed</label>
268
+ <input id="pending_checkbox" name="pending_checkbox" type="checkbox" checked onchange="apply_filters()" value="3"> <label for="pending_checkbox">Pending</label>
269
+ </div>
270
+
271
+ <div id="summary">
272
+ <p id="totals">&nbsp;</p>
273
+ <p id="duration">&nbsp;</p>
274
+ </div>
275
+ </div>
276
+
277
+
278
+ <div class="results">
279
+ <div id="div_group_1" class="example_group passed">
280
+ <dl style="margin-left: 0px;">
281
+ <dt id="example_group_1" class="passed">LooksGood::Configuration</dt>
282
+ </dl>
283
+ </div>
284
+ <div id="div_group_2" class="example_group passed">
285
+ <dl style="margin-left: 15px;">
286
+ <dt id="example_group_2" class="passed">#reference_image_path</dt>
287
+ <script type="text/javascript">moveProgressBar('20.0');</script>
288
+ <dd class="example passed"><span class="passed_spec_name">should default to &lt;Rails.root&gt;/spec/reference_images</span></dd>
289
+ <script type="text/javascript">moveProgressBar('40.0');</script>
290
+ <dd class="example passed"><span class="passed_spec_name">should be overrideable</span></dd>
291
+ </dl>
292
+ </div>
293
+ <div id="div_group_3" class="example_group passed">
294
+ <dl style="margin-left: 0px;">
295
+ <dt id="example_group_3" class="passed">looks_good</dt>
296
+ </dl>
297
+ </div>
298
+ <div id="div_group_4" class="example_group passed">
299
+ <dl style="margin-left: 15px;">
300
+ <dt id="example_group_4" class="passed">creating an initial reference (expected) image</dt>
301
+ <script type="text/javascript">moveProgressBar('60.0');</script>
302
+ <dd class="example passed"><span class="passed_spec_name">should notify that no reference exists for image and create a candidate</span></dd>
303
+ </dl>
304
+ </div>
305
+ <div id="div_group_5" class="example_group passed">
306
+ <dl style="margin-left: 15px;">
307
+ <dt id="example_group_5" class="passed">image comparison</dt>
308
+ <script type="text/javascript">moveProgressBar('80.0');</script>
309
+ <dd class="example passed"><span class="passed_spec_name">captured and referenced images match</span></dd>
310
+ </dl>
311
+ </div>
312
+ <div id="div_group_6" class="example_group passed">
313
+ <dl style="margin-left: 15px;">
314
+ <dt id="example_group_6" class="passed">training mode populates a candidate reference</dt>
315
+ <script type="text/javascript">makeRed('rspec-header');</script>
316
+ <script type="text/javascript">makeRed('div_group_6');</script>
317
+ <script type="text/javascript">makeRed('example_group_6');</script>
318
+ <script type="text/javascript">moveProgressBar('100.0');</script>
319
+ <dd class="example failed">
320
+ <span class="failed_spec_name">should create a reference from a candidate</span>
321
+ <div class="failure" id="failure_1">
322
+ <div class="message"><pre>can't convert nil into String</pre></div>
323
+ <div class="backtrace"><pre>./lib/looks_good.rb:104:in `+'
324
+ ./lib/looks_good.rb:104:in `run'
325
+ ./spec/looks_good_spec.rb:76:in `block (3 levels) in <top (required)>'</pre></div>
326
+ <pre class="ruby"><code><span class="linenum">102</span>
327
+ <span class="linenum">103</span> <span class="keyword">def </span><span class="method">run</span>
328
+ <span class="offending"><span class="linenum">104</span> <span class="ident">puts</span> <span class="punct">&quot;</span><span class="string">-------------</span><span class="punct">&quot;</span> <span class="punct">+</span> <span class="attribute">@reference_image_path</span></span>
329
+ <span class="linenum">105</span> <span class="constant">self</span><span class="punct">.</span><span class="ident">crop_element</span>
330
+ <span class="linenum">106</span> <span class="keyword">end</span></code></pre>
331
+ </div>
332
+ </dd>
333
+ </dl>
334
+ </div>
335
+ <script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>14.828533 seconds</strong>";</script>
336
+ <script type="text/javascript">document.getElementById('totals').innerHTML = "5 examples, 1 failure";</script>
337
+ </div>
338
+ </div>
339
+ </body>
340
+ </html>
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+ include Capybara::DSL
3
+
4
+ describe 'LooksGood' do
5
+
6
+ before(:all) do
7
+ @spec_support_root = spec_support_root
8
+ end
9
+
10
+ before(:each) do
11
+ @ref_path = LooksGood::Configuration.reference_image_path = File.join(spec_support_root, 'ref_path')
12
+ end
13
+
14
+ after(:each) do
15
+ remove_refs(@ref_path)
16
+ config_clean_up
17
+ end
18
+
19
+ describe 'LooksGood, when no reference image exists' do
20
+
21
+ it "will create a reference image" do
22
+ black_element = element_for_spec
23
+ $stdout.should_receive(:puts).with "Saved #{@ref_path}/#{"black.png"} as reference"
24
+
25
+ LooksGood.matches?("black.png", black_element).should be_true
26
+
27
+ File.exists?(File.join(@ref_path, "black.png")).should be_true
28
+ end
29
+ end
30
+
31
+ describe 'LooksGood image comparison' do
32
+
33
+ before(:each) do
34
+ create_square_image(@ref_path, 'black')
35
+ end
36
+
37
+ after(:each) do
38
+ remove_refs(@ref_path)
39
+ config_clean_up
40
+ end
41
+
42
+ it 'will return true if the images are identical' do
43
+ black_element = element_for_spec('#black')
44
+
45
+ LooksGood.matches?("black.png", black_element).should be_true
46
+ end
47
+
48
+ describe 'between different images of the same size' do
49
+
50
+ it 'will return false, creates new diff and candidate images' do
51
+ red_element = element_for_spec('#red')
52
+ expected_error = "element did not match #{"black.png"}. " +
53
+ "A diff image: #{"black.png"} was created in #{@ref_path}/diff/#{"black.png"} " +
54
+ "A new reference #{@ref_path}/candidate/#{"black.png"} can be used to fix the test"
55
+
56
+ expect {LooksGood.matches?("black.png", red_element)}.to raise_error(RuntimeError, expected_error)
57
+
58
+ File.exists?(File.join(@ref_path,'diff', "black.png")).should be_true
59
+ File.exists?(File.join(@ref_path,'candidate', "black.png")).should be_true
60
+ end
61
+
62
+ end
63
+
64
+ describe 'between images of the different size' do
65
+
66
+ it 'will return false, creates new diff and candidate images' do
67
+ red_element = element_for_spec('#different-size')
68
+ expected_error = "element did not match #{"black.png"}. " +
69
+ "A diff image: #{"black.png"} was created in #{@ref_path}/diff/#{"black.png"} " +
70
+ "A new reference #{@ref_path}/candidate/#{"black.png"} can be used to fix the test"
71
+
72
+ expect {LooksGood.matches?("black.png", red_element)}.to raise_error(RuntimeError, expected_error)
73
+
74
+ File.exists?(File.join(@ref_path,'diff', "black.png")).should be_true
75
+ File.exists?(File.join(@ref_path,'candidate', "black.png")).should be_true
76
+ end
77
+
78
+ end
79
+ end
80
+
81
+
82
+
83
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ include Capybara::DSL
3
+
4
+ describe 'rspec matcher' do
5
+
6
+ before(:each) do
7
+ @black_box = 'black.png'
8
+ @ref_path = LooksGood::Configuration.reference_image_path = File.join(spec_support_root, 'ref_path')
9
+ create_images_for_web_page
10
+ end
11
+
12
+ after(:each) do
13
+ config_clean_up
14
+ remove_refs(@ref_path)
15
+ end
16
+
17
+ describe 'initializing and runnin looks_good' do
18
+
19
+ it 'will pass if images matches reference' do
20
+ create_square_image(@ref_path, 'black')
21
+ black_element = element_for_spec("#black")
22
+ black_element.should look_like("black.png")
23
+ end
24
+
25
+ it "will fail if images doesn't matches reference" do
26
+ create_square_image(@ref_path, 'black')
27
+ red_element = element_for_spec("#red")
28
+ expect{red_element.should look_like(@black_box)}.to raise_error
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe LooksGood::CaptureElement do
4
+
5
+ # creating a dummy class to test a module
6
+ class SomeClass
7
+ end
8
+
9
+ before :each do
10
+ subject = SomeClass.new
11
+ subject.extend(LooksGood::CaptureElement)
12
+ end
13
+
14
+ after :each do
15
+ config_clean_up
16
+ end
17
+
18
+ it '.capture should return a cropped image' do
19
+ capybara_element = mock(Capybara::Node::Element)
20
+ position = {:x => 1, :y => 2, :width => 100, :height => 200}
21
+ magick_image = Magick::Image.new(position[:width],position[:height])
22
+
23
+
24
+ subject.should_receive(:get_element_position).with(capybara_element).and_return(position)
25
+ subject.should_receive(:take_screenshot).and_return(magick_image)
26
+ subject.should_receive(:crop_element).and_return(magick_image)
27
+
28
+ image = subject.capture(capybara_element)
29
+ image.class.should == Magick::Image
30
+ end
31
+
32
+ end
33
+
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe LooksGood::Comparison do
4
+
5
+ before do
6
+ apple = Magick::Image.new(100,100) { self.background_color = "green" }
7
+ orange = Magick::Image.new(100,100) { self.background_color = "orange" }
8
+ @apple = LooksGood::Image.new(apple, "apple.png")
9
+ @orange = LooksGood::Image.new(orange, "orange.png")
10
+ end
11
+
12
+ describe 'will compare two images' do
13
+
14
+ it 'will return true if the images are identical' do
15
+ LooksGood::Comparison.new(@apple, @apple).matches?.should == true
16
+ end
17
+
18
+ it 'will return false if the images are different' do
19
+ LooksGood::Comparison.new(@orange, @apple).matches?.should == false
20
+ end
21
+ end
22
+
23
+ describe 'Diff images' do
24
+ describe 'for two images with the same size' do
25
+ it 'will be generated' do
26
+ LooksGood::Comparison.new(@apple, @orange).diff_image.class.should == LooksGood::Image
27
+ end
28
+ end
29
+
30
+ describe 'for two images with different sizes' do
31
+ before do
32
+ @apple_image = Magick::Image.new(30,300) { self.background_color = "green" }
33
+ @orange_image = Magick::Image.new(80,100) { self.background_color = "orange" }
34
+
35
+ @apple = LooksGood::Image.new(@apple_image, "apple.png")
36
+ @orange = LooksGood::Image.new(@orange_image, "orange.png")
37
+
38
+ @diff_image = LooksGood::Comparison.new(@apple, @orange).diff_image
39
+ end
40
+
41
+ it 'will be generated' do
42
+ @diff_image.class.should == LooksGood::Image
43
+ end
44
+
45
+ it 'will be extended to cover the difference in both images' do
46
+ @diff_image.image.columns.should eql 80
47
+ @diff_image.image.rows.should eql 300
48
+ end
49
+
50
+ describe 'with two different offset' do
51
+ before do
52
+ @apple_image.offset = 50
53
+ @orange_image.offset = 2
54
+
55
+ @diff_image = LooksGood::Comparison.new(@apple, @orange).diff_image
56
+ end
57
+
58
+ it 'will remove image offset from the diff image' do
59
+ @diff_image.image.offset.should eql 0
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+ end
66
+ end