zucchini-ios 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -1
- data/CHANGELOG.md +28 -15
- data/README.md +23 -19
- data/Rakefile +1 -0
- data/bin/zucchini +4 -11
- data/lib/zucchini.rb +12 -0
- data/lib/{approver.rb → zucchini/approver.rb} +0 -0
- data/lib/{config.rb → zucchini/config.rb} +0 -0
- data/lib/{detector.rb → zucchini/detector.rb} +0 -0
- data/lib/{feature.rb → zucchini/feature.rb} +25 -22
- data/lib/{generator.rb → zucchini/generator.rb} +5 -5
- data/lib/{report.rb → zucchini/report.rb} +3 -4
- data/lib/zucchini/report/css/zucchini.report.css +241 -0
- data/lib/{report → zucchini/report}/js/jquery.effects.core.js +0 -0
- data/lib/{report → zucchini/report}/js/jquery.js +0 -0
- data/lib/{report → zucchini/report}/js/jquery.ui.core.js +0 -0
- data/lib/zucchini/report/js/zucchini.report.js +59 -0
- data/lib/zucchini/report/template.erb.html +47 -0
- data/lib/{report → zucchini/report}/view.rb +0 -0
- data/lib/{runner.rb → zucchini/runner.rb} +0 -0
- data/lib/{screenshot.rb → zucchini/screenshot.rb} +77 -30
- data/lib/{uia → zucchini/uia}/base.coffee +0 -1
- data/lib/{uia → zucchini/uia}/screen.coffee +5 -4
- data/lib/{version.rb → zucchini/version.rb} +1 -1
- data/spec/lib/{config_spec.rb → zucchini/config_spec.rb} +0 -0
- data/spec/lib/{detector_spec.rb → zucchini/detector_spec.rb} +0 -0
- data/spec/lib/{feature_spec.rb → zucchini/feature_spec.rb} +0 -0
- data/spec/lib/{generator_spec.rb → zucchini/generator_spec.rb} +0 -0
- data/spec/lib/{report_spec.rb → zucchini/report_spec.rb} +0 -0
- data/spec/lib/zucchini/screenshot_spec.rb +164 -0
- data/spec/sample_setup/feature_one/run_data/Run 1/06_sign up_spinner.png b/data/spec/sample_setup/feature_one/run_data/Run 1/06_splash-screen_sign → up_spinner.png +0 -0
- data/spec/sample_setup/support/masks/splash.png +0 -0
- data/spec/spec_helper.rb +14 -10
- data/zucchini-ios.gemspec +8 -9
- metadata +58 -36
- data/lib/report/css/zucchini.report.css +0 -239
- data/lib/report/js/zucchini.report.js +0 -59
- data/lib/report/template.erb +0 -47
- data/spec/lib/screenshot_spec.rb +0 -109
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,59 @@
|
|
1
|
+
var ci = function() { return $(document.body).hasClass('ci') }
|
2
|
+
|
3
|
+
var scrollSurface = function(surface)
|
4
|
+
{
|
5
|
+
if(ci())
|
6
|
+
{
|
7
|
+
setTimeout(function()
|
8
|
+
{
|
9
|
+
surface.animate
|
10
|
+
(
|
11
|
+
{ left: surface.offset().left - surface.parents('.viewport').width() - 26 },
|
12
|
+
1000, 'easeInOutQuint',
|
13
|
+
function()
|
14
|
+
{
|
15
|
+
if(ci())
|
16
|
+
{
|
17
|
+
if($('.screen', surface).last().offset().left <= 27)
|
18
|
+
{
|
19
|
+
setTimeout(function()
|
20
|
+
{
|
21
|
+
surface.parents('.feature').fadeOut(500, function()
|
22
|
+
{
|
23
|
+
surface[0].style.left = 0
|
24
|
+
var next = nextSurface(surface)
|
25
|
+
next.parents('.feature').fadeIn(500, function(){ scrollSurface(next) })
|
26
|
+
})
|
27
|
+
}, 2000)
|
28
|
+
}
|
29
|
+
else scrollSurface(surface)
|
30
|
+
}
|
31
|
+
}
|
32
|
+
)
|
33
|
+
}, 2000)
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
var nextSurface = function(surface)
|
38
|
+
{
|
39
|
+
var next = $('.surface', surface.parents('.feature').next())
|
40
|
+
return !next.length ? $('.surface').first() : next
|
41
|
+
}
|
42
|
+
|
43
|
+
var bindEvents = function(callback)
|
44
|
+
{
|
45
|
+
$('.screen').each(function(){ $(this).click(function()
|
46
|
+
{
|
47
|
+
if(ci())
|
48
|
+
$(document.body).switchClass('ci', '', 100, function() { $('.feature').css({ display: 'block' }) })
|
49
|
+
else
|
50
|
+
$(this).toggleClass('expanded')
|
51
|
+
}) })
|
52
|
+
|
53
|
+
$('.buttons .expand' ).click(function(){ $('.screen', $(this).parents('.feature')).addClass( 'expanded') })
|
54
|
+
$('.buttons .collapse').click(function(){ $('.screen', $(this).parents('.feature')).removeClass('expanded') })
|
55
|
+
|
56
|
+
callback()
|
57
|
+
}
|
58
|
+
|
59
|
+
$(document).ready(function() { bindEvents(function() { scrollSurface($('.surface').first()) }) })
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
3
|
+
|
4
|
+
<head>
|
5
|
+
<title>Test Results: <%= @device[:name] %>, <%= @time %></title>
|
6
|
+
<link rel="stylesheet" href="<%= @assets_path %>/css/zucchini.report.css" type="text/css" media="screen">
|
7
|
+
<script src="<%= @assets_path %>/js/jquery.js"></script>
|
8
|
+
<script src="<%= @assets_path %>/js/jquery.ui.core.js"></script>
|
9
|
+
<script src="<%= @assets_path %>/js/jquery.effects.core.js"></script>
|
10
|
+
<script src="<%= @assets_path %>/js/zucchini.report.js"></script>
|
11
|
+
</head>
|
12
|
+
<body class="<%= @ci %>">
|
13
|
+
<header>
|
14
|
+
<h1><%= @device[:name] %><span class="time"><%= @time %></span></h1>
|
15
|
+
</header>
|
16
|
+
|
17
|
+
<% @features.each_with_index do |f, i| %>
|
18
|
+
<section class="<%= i == 0 ? 'first' : '' %> feature">
|
19
|
+
<h3><%= f.name %></h3>
|
20
|
+
<div class="indicators">
|
21
|
+
<% if !f.stats[:failed].empty? %><div class="failed"><%= f.stats[:failed].length.to_s %></div><% end %>
|
22
|
+
<% if !f.stats[:pending].empty? %><div class="pending"><%= f.stats[:pending].length.to_s %></div><% end %>
|
23
|
+
<% if !f.stats[:passed].empty? %><div class="passed"><%= f.stats[:passed].length.to_s %></div><% end %>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<div class="buttons">
|
27
|
+
<a class="expand left">Expand</a>
|
28
|
+
<a class="collapse right">Collapse</a>
|
29
|
+
</div>
|
30
|
+
|
31
|
+
<div class="viewport">
|
32
|
+
<div class="surface">
|
33
|
+
<% f.screenshots.each do |s| %>
|
34
|
+
<% css_class = s.diff[0].to_s %>
|
35
|
+
<dl class="<%= css_class %> <%= css_class == 'failed' ? 'expanded' :'' %> screen">
|
36
|
+
<dt><%= s.file_name %></dt>
|
37
|
+
<% %W(actual expected difference).each do |type| %>
|
38
|
+
<dd class="<%= s.result_images[type.to_sym] ? '' : 'hidden' %>"><p><%= type.capitalize %></p><img src="<%= s.result_images[type.to_sym] %>"/></dd>
|
39
|
+
<% end %>
|
40
|
+
</dl>
|
41
|
+
<% end %>
|
42
|
+
</div>
|
43
|
+
</div>
|
44
|
+
</section>
|
45
|
+
<% end %>
|
46
|
+
</body>
|
47
|
+
</html>
|
File without changes
|
File without changes
|
@@ -1,57 +1,67 @@
|
|
1
1
|
class Zucchini::Screenshot
|
2
|
-
|
2
|
+
FILE_NAME_PATTERN = /^\d\d_((?<orientation>Unknown|Portrait|PortraitUpsideDown|LandscapeLeft|LandscapeRight|FaceUp|FaceDown)_)?((?<screen>.*)-screen_)?.*$/
|
3
3
|
|
4
|
-
attr_reader :file_path, :file_name
|
4
|
+
attr_reader :file_path, :original_file_path, :file_name
|
5
5
|
attr_accessor :diff, :masks_paths, :masked_paths, :test_path, :diff_path
|
6
6
|
|
7
7
|
def initialize(file_path, device, unmatched_pending = false)
|
8
|
-
file_name = File.basename(file_path)
|
9
8
|
@original_file_path = file_path
|
10
|
-
@
|
11
|
-
|
12
|
-
@
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@
|
18
|
-
@
|
9
|
+
@file_path = file_path.dup
|
10
|
+
|
11
|
+
@device = device
|
12
|
+
|
13
|
+
match = FILE_NAME_PATTERN.match(File.basename(@file_path))
|
14
|
+
|
15
|
+
if match
|
16
|
+
@orientation = match[:orientation]
|
17
|
+
@screen = match[:screen]
|
18
|
+
@file_path.gsub!("_#{@screen}-screen", '') if @screen
|
19
|
+
@file_path.gsub!("_#{@orientation}", '') if @orientation
|
19
20
|
end
|
20
21
|
|
22
|
+
@file_name = File.basename(@file_path)
|
23
|
+
|
21
24
|
unless unmatched_pending
|
22
25
|
file_base_path = File.dirname(@file_path)
|
23
26
|
|
27
|
+
support_masks_path = "#{file_base_path}/../../../support/masks"
|
28
|
+
|
24
29
|
@masks_paths = {
|
25
|
-
:global => "#{
|
30
|
+
:global => "#{support_masks_path}/#{@device[:screen]}.png",
|
31
|
+
:screen => "#{support_masks_path}/#{@screen.to_s.underscore}.png",
|
26
32
|
:specific => "#{file_base_path}/../../masks/#{@device[:screen]}/#{@file_name}"
|
27
33
|
}
|
28
34
|
|
29
35
|
masked_path = "#{file_base_path}/../Masked/actual/#{@file_name}"
|
30
|
-
@masked_paths = { :
|
36
|
+
@masked_paths = { :global => masked_path, :screen => masked_path, :specific => masked_path }
|
31
37
|
|
32
38
|
@diff_path = "#{file_base_path}/../Diff/#{@file_name}"
|
33
39
|
end
|
40
|
+
|
41
|
+
preprocess
|
34
42
|
end
|
35
43
|
|
36
|
-
def
|
37
|
-
return
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
when 'PortraitUpsideDown' then 180
|
44
|
+
def preprocess
|
45
|
+
return if @original_file_path == @file_path
|
46
|
+
|
47
|
+
if @orientation
|
48
|
+
rotate
|
42
49
|
else
|
43
|
-
|
50
|
+
FileUtils.rm @file_path if File.exists?(@file_path)
|
51
|
+
FileUtils.mv @original_file_path, @file_path
|
44
52
|
end
|
45
|
-
`convert \"#{@original_file_path}\" -rotate \"#{degrees}\" \"#{@file_path}\"`
|
46
|
-
FileUtils.rm @original_file_path
|
47
53
|
end
|
48
54
|
|
49
55
|
def mask
|
50
|
-
|
51
|
-
|
56
|
+
create_masked_paths_dirs
|
57
|
+
masked_path = apply_mask(@file_path, :global)
|
58
|
+
|
59
|
+
if mask?(:screen)
|
60
|
+
masked_path = apply_mask(masked_path, :screen)
|
61
|
+
end
|
52
62
|
|
53
|
-
if
|
54
|
-
|
63
|
+
if mask?(:specific)
|
64
|
+
apply_mask(masked_path, :specific)
|
55
65
|
end
|
56
66
|
end
|
57
67
|
|
@@ -62,7 +72,7 @@ class Zucchini::Screenshot
|
|
62
72
|
FileUtils.mkdir_p(File.dirname(@diff_path))
|
63
73
|
|
64
74
|
compare_command = "compare -metric AE -fuzz 2% -dissimilarity-threshold 1 -subimage-search"
|
65
|
-
out = `#{compare_command} \"#{@masked_paths[:
|
75
|
+
out = `#{compare_command} \"#{@masked_paths[:specific]}\" \"#{@test_path}\" \"#{@diff_path}\" 2>&1`
|
66
76
|
out.chomp!
|
67
77
|
@diff = (out == '0') ? [:passed, nil] : [:failed, out]
|
68
78
|
@diff = [:pending, @diff[1]] if @pending
|
@@ -73,7 +83,7 @@ class Zucchini::Screenshot
|
|
73
83
|
|
74
84
|
def result_images
|
75
85
|
@result_images ||= {
|
76
|
-
:actual => @masked_paths && File.exists?(@masked_paths[:
|
86
|
+
:actual => @masked_paths && File.exists?(@masked_paths[:specific]) ? @masked_paths[:specific] : nil,
|
77
87
|
:expected => @test_path && File.exists?(@test_path) ? @test_path : nil,
|
78
88
|
:difference => @diff_path && File.exists?(@diff_path) ? @diff_path : nil
|
79
89
|
}
|
@@ -92,10 +102,47 @@ class Zucchini::Screenshot
|
|
92
102
|
|
93
103
|
reference = Zucchini::Screenshot.new(reference_file_path, @device)
|
94
104
|
reference.masks_paths = @masks_paths
|
95
|
-
reference.masked_paths = { :
|
105
|
+
reference.masked_paths = { :global => output_path, :screen => output_path, :specific => output_path }
|
96
106
|
reference.mask
|
97
107
|
end
|
98
108
|
end
|
99
109
|
end
|
100
110
|
|
111
|
+
private
|
112
|
+
def mask?(mask)
|
113
|
+
@masks_paths[mask] && File.exists?(@masks_paths[mask])
|
114
|
+
end
|
115
|
+
|
116
|
+
def create_masked_paths_dirs
|
117
|
+
@masked_paths.each { |name, path| FileUtils.mkdir_p(File.dirname(path)) }
|
118
|
+
end
|
119
|
+
|
120
|
+
def apply_mask(src_path, mask)
|
121
|
+
mask_path = @masks_paths[mask]
|
122
|
+
dest_path = @masked_paths[mask]
|
123
|
+
`convert -page +0+0 \"#{src_path}\" -page +0+0 \"#{mask_path}\" -flatten \"#{dest_path}\"`
|
124
|
+
return dest_path
|
125
|
+
end
|
126
|
+
|
127
|
+
def rotate
|
128
|
+
degrees = case @orientation
|
129
|
+
when 'LandscapeRight' then 90
|
130
|
+
when 'LandscapeLeft' then 270
|
131
|
+
when 'PortraitUpsideDown' then 180
|
132
|
+
else
|
133
|
+
0
|
134
|
+
end
|
135
|
+
`convert \"#{@original_file_path}\" -rotate \"#{degrees}\" \"#{@file_path}\"`
|
136
|
+
FileUtils.rm @original_file_path
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class String
|
141
|
+
def underscore
|
142
|
+
self.gsub(/::/, '/').
|
143
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
144
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
145
|
+
tr("-", "_").
|
146
|
+
downcase
|
147
|
+
end
|
101
148
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class Screen
|
2
|
-
takeScreenshot: (
|
2
|
+
takeScreenshot: (screenshot_name) ->
|
3
3
|
orientation = switch app.interfaceOrientation()
|
4
4
|
when 0 then 'Unknown'
|
5
5
|
when 1 then 'Portrait'
|
@@ -8,7 +8,8 @@ class Screen
|
|
8
8
|
when 4 then 'LandscapeRight'
|
9
9
|
when 5 then 'FaceUp'
|
10
10
|
when 6 then 'FaceDown'
|
11
|
-
|
11
|
+
puts "Screenshot of screen '#{@name}' taken"
|
12
|
+
target.captureScreenWithName("#{orientation}_#{@name}-screen_#{screenshot_name}")
|
12
13
|
|
13
14
|
constructor: (@name) ->
|
14
15
|
|
@@ -17,8 +18,8 @@ class Screen
|
|
17
18
|
'Take a screenshot$' : ->
|
18
19
|
@takeScreenshot(@name)
|
19
20
|
|
20
|
-
'Take a screenshot named "([^"]*)"$' : (
|
21
|
-
@takeScreenshot(
|
21
|
+
'Take a screenshot named "([^"]*)"$' : (screenshot_name) ->
|
22
|
+
@takeScreenshot(screenshot_name)
|
22
23
|
|
23
24
|
'Tap "([^"]*)"$' : (element) ->
|
24
25
|
raise "Element '#{element}' not defined for the screen '#{@name}'" unless @elements[element]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'digest/md5'
|
3
|
+
require 'tmpdir'
|
4
|
+
|
5
|
+
def md5(blob)
|
6
|
+
Digest::MD5.hexdigest(blob)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Zucchini::Screenshot do
|
10
|
+
describe "general" do
|
11
|
+
let (:device) { { :name => "iPhone 4S", :screen => "retina_ios5", :udid => "rspec987654" } }
|
12
|
+
let (:screen) { "splash" }
|
13
|
+
let (:base_path) { "spec/sample_setup/feature_one" }
|
14
|
+
let (:original_path) { "#{base_path}/run_data/Run\ 1/06_splash-screen_sign\ up_spinner.png" }
|
15
|
+
|
16
|
+
before do
|
17
|
+
@screenshot = Zucchini::Screenshot.new(original_path, device)
|
18
|
+
@screenshot.masked_paths = {
|
19
|
+
:global => "#{base_path}/global_masked.png",
|
20
|
+
:screen => "#{base_path}/screen_masked.png",
|
21
|
+
:specific => "#{base_path}/specific_masked.png"
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
after do
|
26
|
+
FileUtils.mv(@screenshot.file_path, original_path) if File.exists?(@screenshot.file_path)
|
27
|
+
|
28
|
+
@screenshot.masked_paths.each do |k, path|
|
29
|
+
FileUtils.rm(path) if File.exists?(path)
|
30
|
+
end
|
31
|
+
|
32
|
+
FileUtils.rm_rf("#{base_path}/run_data/Masked")
|
33
|
+
FileUtils.rm_rf(@screenshot.diff_path)
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "mask" do
|
37
|
+
let (:checksums) {
|
38
|
+
checksums = {}
|
39
|
+
|
40
|
+
checksums[:original] = md5(File.read(@screenshot.file_path))
|
41
|
+
|
42
|
+
if File.exists?(@screenshot.masked_paths[:global])
|
43
|
+
checksums[:global_masked] = md5(File.read(@screenshot.masked_paths[:global]))
|
44
|
+
end
|
45
|
+
|
46
|
+
if File.exists?(@screenshot.masked_paths[:screen])
|
47
|
+
checksums[:screen_masked] = md5(File.read(@screenshot.masked_paths[:screen]))
|
48
|
+
end
|
49
|
+
|
50
|
+
if File.exists?(@screenshot.masked_paths[:specific])
|
51
|
+
checksums[:specific_masked] = md5(File.read(@screenshot.masked_paths[:specific]))
|
52
|
+
end
|
53
|
+
|
54
|
+
checksums
|
55
|
+
}
|
56
|
+
|
57
|
+
it "should apply a standard global mask based on the device" do
|
58
|
+
@screenshot.mask
|
59
|
+
File.exists?(@screenshot.masked_paths[:global]).should be true
|
60
|
+
checksums[:global_masked].should_not be_equal checksums[:original]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should apply a screen-specific mask if it exists" do
|
64
|
+
@screenshot.mask
|
65
|
+
File.exists?(@screenshot.masked_paths[:screen]).should be true
|
66
|
+
checksums[:screen_masked].should_not be_equal checksums[:original]
|
67
|
+
checksums[:specific_masked].should_not be_equal checksums[:global_masked]
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should not apply a screen mask if it does not exist" do
|
71
|
+
@screenshot.masks_paths[:screen] = nil
|
72
|
+
@screenshot.mask
|
73
|
+
File.exists?(@screenshot.masked_paths[:screen]).should_not be true
|
74
|
+
checksums[:global_masked].should_not be_equal checksums[:original]
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should not apply a specific mask if it does not exist" do
|
78
|
+
@screenshot.masks_paths[:specific] = nil
|
79
|
+
@screenshot.mask
|
80
|
+
File.exists?(@screenshot.masked_paths[:specific]).should_not be true
|
81
|
+
checksums[:global_masked].should_not be_equal checksums[:original]
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should apply a screenshot-specific mask if it exists" do
|
85
|
+
@screenshot.mask
|
86
|
+
File.exists?(@screenshot.masked_paths[:specific]).should be true
|
87
|
+
checksums[:specific_masked].should_not be_equal checksums[:original]
|
88
|
+
checksums[:specific_masked].should_not be_equal checksums[:screen_masked]
|
89
|
+
checksums[:specific_masked].should_not be_equal checksums[:global_masked]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "compare" do
|
94
|
+
context "images are identical" do
|
95
|
+
it "should have a passed indicator in the diff" do
|
96
|
+
@screenshot.mask
|
97
|
+
@screenshot.compare
|
98
|
+
@screenshot.diff.should eq [:passed, nil]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "images are different" do
|
103
|
+
it "should have a failed indicator in the diff" do
|
104
|
+
@screenshot.stub!(:mask_reference)
|
105
|
+
@screenshot.test_path = "#{base_path}/reference/#{device[:screen]}/06_sign\ up_spinner_error.png"
|
106
|
+
@screenshot.mask
|
107
|
+
@screenshot.compare
|
108
|
+
@screenshot.diff.should eq [:failed, "188162"]
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should have a failed indicator in the diff with no screen mask" do
|
112
|
+
@screenshot.stub!(:mask_reference)
|
113
|
+
@screenshot.test_path = "#{base_path}/reference/#{device[:screen]}/06_sign\ up_spinner_error.png"
|
114
|
+
@screenshot.masks_paths[:screen] = nil
|
115
|
+
@screenshot.mask
|
116
|
+
@screenshot.compare
|
117
|
+
@screenshot.diff.should eq [:failed, "3017"]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "mask reference" do
|
123
|
+
it "should create masked versions of reference screenshots" do
|
124
|
+
@screenshot.mask
|
125
|
+
@screenshot.mask_reference
|
126
|
+
|
127
|
+
File.exists?(@screenshot.test_path).should be_true
|
128
|
+
md5(File.read(@screenshot.test_path)).should_not be_equal md5(File.read("#{base_path}/reference/#{device[:screen]}/06_sign\ up_spinner.png"))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "rotate" do
|
134
|
+
let (:sample_screenshots_path) { "spec/sample_screenshots" }
|
135
|
+
let (:reference_screenshot_path) { File.join(sample_screenshots_path, "rotated/01_Screenshot.png") }
|
136
|
+
let (:reference_md5) { md5(File.read(reference_screenshot_path)) }
|
137
|
+
let (:temp_dir) { Dir.mktmpdir }
|
138
|
+
before do
|
139
|
+
`cp #{File.join(sample_screenshots_path, "*")} #{temp_dir}`
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should rotate the landscape-left screenshot" do
|
143
|
+
screenshot = Zucchini::Screenshot.new(File.join(temp_dir,'01_LandscapeLeft_Screenshot.png'), nil, true)
|
144
|
+
File.exists?(File.join(temp_dir,'01_LandscapeLeft_Screenshot.png')).should be_false
|
145
|
+
File.exists?(File.join(temp_dir,'01_Screenshot.png')).should be_true
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should rotate the landscape-right screenshot" do
|
149
|
+
screenshot = Zucchini::Screenshot.new(File.join(temp_dir,'02_LandscapeRight_Screenshot.png'), nil, true)
|
150
|
+
File.exists?(File.join(temp_dir,'02_LandscapeRight_Screenshot.png')).should be_false
|
151
|
+
File.exists?(File.join(temp_dir,'02_Screenshot.png')).should be_true
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should rotate the upside-down screenshot" do
|
155
|
+
screenshot = Zucchini::Screenshot.new(File.join(temp_dir,'03_PortraitUpsideDown_Screenshot.png'), nil, true)
|
156
|
+
File.exists?(File.join(temp_dir,'02_PortraitUpsideDown_Screenshot.png')).should be_false
|
157
|
+
File.exists?(File.join(temp_dir,'03_Screenshot.png')).should be_true
|
158
|
+
end
|
159
|
+
|
160
|
+
after do
|
161
|
+
FileUtils.remove_entry temp_dir
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|