zucchini-ios 0.5.9 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/lib/config.rb +1 -1
  2. data/lib/feature.rb +1 -0
  3. data/lib/screenshot.rb +36 -14
  4. data/lib/uia/screen.coffee +15 -4
  5. data/lib/version.rb +1 -1
  6. data/templates/project/features/support/masks/ipad_retina_ios6.png +0 -0
  7. metadata +73 -116
  8. data/spec/lib/config_spec.rb +0 -36
  9. data/spec/lib/detector_spec.rb +0 -52
  10. data/spec/lib/feature_spec.rb +0 -69
  11. data/spec/lib/generator_spec.rb +0 -27
  12. data/spec/lib/report_spec.rb +0 -31
  13. data/spec/lib/screenshot_spec.rb +0 -73
  14. data/spec/sample_setup/feature_one/feature.zucchini +0 -1
  15. data/spec/sample_setup/feature_one/masks/retina_ios5/06_sign up_spinner.png +0 -0
  16. data/spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner.png +0 -0
  17. data/spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner_error.png +0 -0
  18. data/spec/sample_setup/feature_one/run_data/Run 1/06_sign up_spinner.png +0 -0
  19. data/spec/sample_setup/feature_three/feature.zucchini +0 -1
  20. data/spec/sample_setup/feature_two/feature.zucchini +0 -1
  21. data/spec/sample_setup/feature_two/masks/retina_ios5/06_sign up_spinner.png +0 -0
  22. data/spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner.png +0 -0
  23. data/spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner_error.png +0 -0
  24. data/spec/sample_setup/feature_two/run_data/Run 1/06_sign up_spinner.png +0 -0
  25. data/spec/sample_setup/support/config.yml +0 -16
  26. data/spec/sample_setup/support/lib/helpers.coffee +0 -3
  27. data/spec/sample_setup/support/masks/retina_ios5.png +0 -0
  28. data/spec/sample_setup/support/screens/splash.coffee +0 -8
  29. data/spec/sample_setup_2/support/config.yml +0 -15
  30. data/spec/spec_helper.rb +0 -18
  31. data/zucchini-ios.gemspec +0 -27
data/lib/config.rb CHANGED
@@ -21,7 +21,7 @@ module Zucchini
21
21
 
22
22
  def self.app
23
23
  device_name = ENV['ZUCCHINI_DEVICE'] || @@default_device_name
24
- app_path = File.absolute_path(devices[device_name]['app'] || @@config['app'])
24
+ app_path = File.absolute_path(devices[device_name]['app'] || @@config['app'] || ENV['ZUCCHINI_APP'])
25
25
 
26
26
  if device_name == 'iOS Simulator' && !File.exists?(app_path)
27
27
  raise "Can't find application at path #{app_path}"
data/lib/feature.rb CHANGED
@@ -31,6 +31,7 @@ class Zucchini::Feature
31
31
  @screenshots ||= Dir.glob("#{run_data_path}/Run\ 1/*.png").map do |file|
32
32
  screenshot = Zucchini::Screenshot.new(file, @device)
33
33
  if process
34
+ screenshot.rotate
34
35
  screenshot.mask
35
36
  screenshot.compare
36
37
  end
data/lib/screenshot.rb CHANGED
@@ -1,29 +1,49 @@
1
1
  class Zucchini::Screenshot
2
+ ORIENTATION = /^\d\d_(?<orientation>(Unknown|Portrait|PortraitUpsideDown|LandscapeLeft|LandscapeRight|FaceUp|FaceDown))_.*$/
3
+
2
4
  attr_reader :file_path, :file_name
3
- attr_accessor :diff, :masks_paths, :masked_paths, :test_path, :diff_path, :compare_cmd
5
+ attr_accessor :diff, :masks_paths, :masked_paths, :test_path, :diff_path
4
6
 
5
7
  def initialize(file_path, device, unmatched_pending = false)
6
- @file_path = file_path
7
- @file_name = File.basename(@file_path)
8
+ file_name = File.basename(file_path)
9
+ @original_file_path = file_path
8
10
  @device = device
9
11
 
10
- @compare_cmd = "compare -metric AE -fuzz 2% -dissimilarity-threshold 1 -subimage-search"
12
+ @orientation = (match = ORIENTATION.match(file_name)) ? match[:orientation] : nil
13
+ if @orientation
14
+ @file_name = file_name.gsub("_#{@orientation}", '')
15
+ @file_path = File.join(File.dirname(file_path),@file_name)
16
+ else
17
+ @file_name = file_name
18
+ @file_path = file_path
19
+ end
11
20
 
12
21
  unless unmatched_pending
13
- @file_base_path = File.dirname(@file_path)
22
+ file_base_path = File.dirname(@file_path)
14
23
 
15
24
  @masks_paths = {
16
- :global => "#{@file_base_path}/../../../support/masks/#{@device[:screen]}.png",
17
- :specific => "#{@file_base_path}/../../masks/#{@device[:screen]}/#{@file_name}"
25
+ :global => "#{file_base_path}/../../../support/masks/#{@device[:screen]}.png",
26
+ :specific => "#{file_base_path}/../../masks/#{@device[:screen]}/#{@file_name}"
18
27
  }
19
28
 
20
- masked_path = "#{@file_base_path}/../Masked/actual/#{@file_name}"
29
+ masked_path = "#{file_base_path}/../Masked/actual/#{@file_name}"
21
30
  @masked_paths = { :globally => masked_path, :specifically => masked_path }
22
31
 
23
- @test_path = nil
24
- @pending = false
25
- @diff_path = "#{@file_base_path}/../Diff/#{@file_name}"
32
+ @diff_path = "#{file_base_path}/../Diff/#{@file_name}"
33
+ end
34
+ end
35
+
36
+ def rotate
37
+ return unless @orientation
38
+ degrees = case @orientation
39
+ when 'LandscapeRight' then 90
40
+ when 'LandscapeLeft' then 270
41
+ when 'PortraitUpsideDown' then 180
42
+ else
43
+ 0
26
44
  end
45
+ `convert \"#{@original_file_path}\" -rotate \"#{degrees}\" \"#{@file_path}\"`
46
+ FileUtils.rm @original_file_path
27
47
  end
28
48
 
29
49
  def mask
@@ -41,7 +61,8 @@ class Zucchini::Screenshot
41
61
  if @test_path
42
62
  FileUtils.mkdir_p(File.dirname(@diff_path))
43
63
 
44
- out = `#{@compare_cmd} \"#{@masked_paths[:specifically]}\" \"#{@test_path}\" \"#{@diff_path}\" 2>&1`
64
+ compare_command = "compare -metric AE -fuzz 2% -dissimilarity-threshold 1 -subimage-search"
65
+ out = `#{compare_command} \"#{@masked_paths[:specifically]}\" \"#{@test_path}\" \"#{@diff_path}\" 2>&1`
45
66
  @diff = (out == "0\n") ? [:passed, nil] : [:failed, out]
46
67
  @diff = [:pending, @diff[1]] if @pending
47
68
  else
@@ -58,9 +79,10 @@ class Zucchini::Screenshot
58
79
  end
59
80
 
60
81
  def mask_reference
82
+ file_base_path = File.dirname(@file_path)
61
83
  %W(reference pending).each do |reference_type|
62
- reference_file_path = "#{@file_base_path}/../../#{reference_type}/#{@device[:screen]}/#{@file_name}"
63
- output_path = "#{@file_base_path}/../Masked/#{reference_type}/#{@file_name}"
84
+ reference_file_path = "#{file_base_path}/../../#{reference_type}/#{@device[:screen]}/#{@file_name}"
85
+ output_path = "#{file_base_path}/../Masked/#{reference_type}/#{@file_name}"
64
86
 
65
87
  if File.exists?(reference_file_path)
66
88
  @test_path = output_path
@@ -1,14 +1,25 @@
1
1
  class Screen
2
+ takeScreenshot: (name) ->
3
+ orientation = switch app.interfaceOrientation()
4
+ when 0 then 'Unknown'
5
+ when 1 then 'Portrait'
6
+ when 2 then 'PortraitUpsideDown'
7
+ when 3 then 'LandscapeLeft'
8
+ when 4 then 'LandscapeRight'
9
+ when 5 then 'FaceUp'
10
+ when 6 then 'FaceDown'
11
+ target.captureScreenWithName("#{orientation}_#{name}")
12
+
2
13
  constructor: (@name) ->
3
14
  if @anchor then target.waitForElement @anchor()
4
15
 
5
16
  elements: {}
6
17
  actions :
7
18
  'Take a screenshot$' : ->
8
- target.captureScreenWithName(@name)
19
+ @takeScreenshot(@name)
9
20
 
10
21
  'Take a screenshot named "([^"]*)"$' : (name) ->
11
- target.captureScreenWithName(name)
22
+ @takeScreenshot(name)
12
23
 
13
24
  'Tap "([^"]*)"$' : (element) ->
14
25
  raise "Element '#{element}' not defined for the screen '#{@name}'" unless @elements[element]
@@ -29,12 +40,12 @@ class Screen
29
40
  raise "Element '#{element}' not defined for the screen '#{@name}'" unless @elements[element]
30
41
  @elements[element]().setValue ""
31
42
 
32
- 'Cancel the alert' : ->
43
+ 'Cancel the alert$' : ->
33
44
  alert = app.alert()
34
45
  raise "No alert found to dismiss on screen '#{@name}'" if isNullElement alert
35
46
  alert.cancelButton().tap()
36
47
 
37
- 'Confirm the alert' : ->
48
+ 'Confirm the alert$' : ->
38
49
  alert = app.alert()
39
50
  raise "No alert found to dismiss on screen '#{@name}'" if isNullElement alert
40
51
  alert.defaultButton().tap()
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Zucchini
2
- VERSION = "0.5.9"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,75 +1,70 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: zucchini-ios
3
- version: !ruby/object:Gem::Version
4
- version: 0.5.9
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 6
8
+ - 0
9
+ version: 0.6.0
6
10
  platform: ruby
7
- authors:
11
+ authors:
8
12
  - Vasily Mikhaylichenko
9
13
  - Rajesh Kumar
10
14
  - Kevin O'Neill
11
15
  autorequire:
12
16
  bindir: bin
13
17
  cert_chain: []
14
- date: 2013-02-05 00:00:00.000000000 Z
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
18
+
19
+ date: 2013-03-31 00:00:00 +11:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
17
23
  name: clamp
18
- requirement: !ruby/object:Gem::Requirement
19
- none: false
20
- requirements:
21
- - - ! '>='
22
- - !ruby/object:Gem::Version
23
- version: '0'
24
- type: :runtime
25
24
  prerelease: false
26
- version_requirements: !ruby/object:Gem::Requirement
27
- none: false
28
- requirements:
29
- - - ! '>='
30
- - !ruby/object:Gem::Version
31
- version: '0'
32
- - !ruby/object:Gem::Dependency
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
33
35
  name: rspec
34
- requirement: !ruby/object:Gem::Requirement
35
- none: false
36
- requirements:
37
- - - ! '>='
38
- - !ruby/object:Gem::Version
39
- version: '0'
40
- type: :development
41
36
  prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- none: false
44
- requirements:
45
- - - ! '>='
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- - !ruby/object:Gem::Dependency
49
- name: watchr
50
- requirement: !ruby/object:Gem::Requirement
51
- none: false
52
- requirements:
53
- - - ! '>='
54
- - !ruby/object:Gem::Version
55
- version: '0'
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
56
44
  type: :development
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: watchr
57
48
  prerelease: false
58
- version_requirements: !ruby/object:Gem::Requirement
59
- none: false
60
- requirements:
61
- - - ! '>='
62
- - !ruby/object:Gem::Version
63
- version: '0'
64
- description: Zucchini follows simple walkthrough scenarios for your iOS app, takes
65
- screenshots and compares them to the reference ones.
66
- email:
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ type: :development
57
+ version_requirements: *id003
58
+ description: Zucchini follows simple walkthrough scenarios for your iOS app, takes screenshots and compares them to the reference ones.
59
+ email:
67
60
  - vaskas@zucchiniframework.org
68
- executables:
61
+ executables:
69
62
  - zucchini
70
63
  extensions: []
64
+
71
65
  extra_rdoc_files: []
72
- files:
66
+
67
+ files:
73
68
  - .gitignore
74
69
  - .travis.yml
75
70
  - Gemfile
@@ -96,29 +91,6 @@ files:
96
91
  - lib/uia/base.coffee
97
92
  - lib/uia/screen.coffee
98
93
  - lib/version.rb
99
- - spec/lib/config_spec.rb
100
- - spec/lib/detector_spec.rb
101
- - spec/lib/feature_spec.rb
102
- - spec/lib/generator_spec.rb
103
- - spec/lib/report_spec.rb
104
- - spec/lib/screenshot_spec.rb
105
- - spec/sample_setup/feature_one/feature.zucchini
106
- - spec/sample_setup/feature_one/masks/retina_ios5/06_sign up_spinner.png
107
- - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner.png
108
- - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner_error.png
109
- - spec/sample_setup/feature_one/run_data/Run 1/06_sign up_spinner.png
110
- - spec/sample_setup/feature_three/feature.zucchini
111
- - spec/sample_setup/feature_two/feature.zucchini
112
- - spec/sample_setup/feature_two/masks/retina_ios5/06_sign up_spinner.png
113
- - spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner.png
114
- - spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner_error.png
115
- - spec/sample_setup/feature_two/run_data/Run 1/06_sign up_spinner.png
116
- - spec/sample_setup/support/config.yml
117
- - spec/sample_setup/support/lib/helpers.coffee
118
- - spec/sample_setup/support/masks/retina_ios5.png
119
- - spec/sample_setup/support/screens/splash.coffee
120
- - spec/sample_setup_2/support/config.yml
121
- - spec/spec_helper.rb
122
94
  - templates/feature/feature.zucchini
123
95
  - templates/feature/masks/retina_ios5/.gitkeep
124
96
  - templates/feature/pending/retina_ios5/.gitkeep
@@ -128,56 +100,41 @@ files:
128
100
  - templates/project/features/support/config.yml
129
101
  - templates/project/features/support/lib/helpers.coffee
130
102
  - templates/project/features/support/masks/ipad_ios5.png
103
+ - templates/project/features/support/masks/ipad_retina_ios6.png
131
104
  - templates/project/features/support/masks/low_ios4.png
132
105
  - templates/project/features/support/masks/retina_ios5.png
133
106
  - templates/project/features/support/screens/welcome.coffee
134
- - zucchini-ios.gemspec
107
+ has_rdoc: true
135
108
  homepage: http://www.zucchiniframework.org
136
- licenses:
109
+ licenses:
137
110
  - BSD
138
111
  post_install_message:
139
112
  rdoc_options: []
140
- require_paths:
113
+
114
+ require_paths:
141
115
  - lib
142
- required_ruby_version: !ruby/object:Gem::Requirement
143
- none: false
144
- requirements:
145
- - - ! '>='
146
- - !ruby/object:Gem::Version
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ segments:
121
+ - 1
122
+ - 9
123
+ - 2
147
124
  version: 1.9.2
148
- required_rubygems_version: !ruby/object:Gem::Requirement
149
- none: false
150
- requirements:
151
- - - ! '>='
152
- - !ruby/object:Gem::Version
153
- version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ segments:
130
+ - 0
131
+ version: "0"
154
132
  requirements: []
133
+
155
134
  rubyforge_project:
156
- rubygems_version: 1.8.23
135
+ rubygems_version: 1.3.6
157
136
  signing_key:
158
137
  specification_version: 3
159
138
  summary: Functional testing framework for iOS-powered devices
160
- test_files:
161
- - spec/lib/config_spec.rb
162
- - spec/lib/detector_spec.rb
163
- - spec/lib/feature_spec.rb
164
- - spec/lib/generator_spec.rb
165
- - spec/lib/report_spec.rb
166
- - spec/lib/screenshot_spec.rb
167
- - spec/sample_setup/feature_one/feature.zucchini
168
- - spec/sample_setup/feature_one/masks/retina_ios5/06_sign up_spinner.png
169
- - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner.png
170
- - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner_error.png
171
- - spec/sample_setup/feature_one/run_data/Run 1/06_sign up_spinner.png
172
- - spec/sample_setup/feature_three/feature.zucchini
173
- - spec/sample_setup/feature_two/feature.zucchini
174
- - spec/sample_setup/feature_two/masks/retina_ios5/06_sign up_spinner.png
175
- - spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner.png
176
- - spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner_error.png
177
- - spec/sample_setup/feature_two/run_data/Run 1/06_sign up_spinner.png
178
- - spec/sample_setup/support/config.yml
179
- - spec/sample_setup/support/lib/helpers.coffee
180
- - spec/sample_setup/support/masks/retina_ios5.png
181
- - spec/sample_setup/support/screens/splash.coffee
182
- - spec/sample_setup_2/support/config.yml
183
- - spec/spec_helper.rb
139
+ test_files: []
140
+
@@ -1,36 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Zucchini::Config do
4
- before(:all) { Zucchini::Config.base_path = "spec/sample_setup" }
5
-
6
- describe "device" do
7
- context "device present in config.yml" do
8
- it "should return the device hash" do
9
- Zucchini::Config.device("My iDevice").should eq({:name =>"My iDevice", :udid =>"lolffb28d74a6fraj2156090784avasc50725dd0", :screen =>"ipad_ios5"})
10
- end
11
- end
12
-
13
- context "device not present in config.yml" do
14
- it "should raise an error" do
15
- expect { Zucchini::Config.device("My Android Phone")}.to raise_error "Device not listed in config.yml"
16
- end
17
- end
18
-
19
- context "default device" do
20
- it "should use default device if device name argument is nil" do
21
- Zucchini::Config.device(nil).should eq({:name =>"Default Device", :screen =>"low_ios5", :udid => nil})
22
- end
23
-
24
- it "should raise error if no default device provided" do
25
- Zucchini::Config.base_path = "spec/sample_setup_2"
26
- expect { Zucchini::Config.device(nil) }.to raise_error "Neither default device nor ZUCCHINI_DEVICE environment variable was set"
27
- end
28
- end
29
- end
30
-
31
- describe "url" do
32
- it "should return a full URL string for a given server name" do
33
- Zucchini::Config.url('backend', '/api').should eq "http://192.168.1.2:8080/api"
34
- end
35
- end
36
- end
@@ -1,52 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Zucchini::Detector do
4
- before do
5
- detector.path = "spec/sample_setup/feature_one"
6
- ENV['ZUCCHINI_DEVICE'] = 'My iDevice'
7
- end
8
-
9
- let (:detector) { Zucchini::Detector.new(nil) }
10
-
11
- describe "execute" do
12
- subject { lambda { detector.execute } }
13
-
14
- context "feature directory doesn't exist" do
15
- before { detector.path = "spec/sample_setup/erroneous_feature" }
16
- it { should raise_error "Directory spec/sample_setup/erroneous_feature does not exist" }
17
- end
18
-
19
- context "device hasn't been found" do
20
- before { ENV['ZUCCHINI_DEVICE'] = 'My Android Phone' }
21
- it { should raise_error "Device not listed in config.yml" }
22
- end
23
- end
24
-
25
- describe "detect features" do
26
- subject { lambda { detector.detect_features(@path) } }
27
-
28
- context "path to a single feature" do
29
- before { @path = "spec/sample_setup/feature_one" }
30
- it "should detect it" do
31
- subject.call[0].path.should eq @path
32
- end
33
- end
34
-
35
- context "path to a directory with features" do
36
- before { @path = File.expand_path("spec/sample_setup") }
37
- it "should detect all features in it" do
38
- subject.call.length.should eq 3
39
- end
40
- end
41
-
42
- context "path to a non-feature directory" do
43
- before do
44
- @path = File.expand_path("spec/sample_setup/bad_feature")
45
- FileUtils.mkdir(@path)
46
- end
47
-
48
- it { should raise_error }
49
- after { FileUtils.rmdir(@path) }
50
- end
51
- end
52
- end
@@ -1,69 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Zucchini::Feature do
4
- let(:path) { './spec/sample_setup/feature_one' }
5
- let(:feature) { Zucchini::Feature.new(path) }
6
-
7
- after(:all) { FileUtils.rm_rf Dir.glob("#{path}/run_data/feature.*") }
8
-
9
- describe "#compile_js" do
10
- before { feature.compile_js }
11
-
12
- it "should strip comments from the feature file" do
13
- File.read("#{feature.run_data_path}/feature.coffee").index('#').should be_nil
14
- end
15
-
16
- describe "feature.js output" do
17
- subject { File.read("#{feature.run_data_path}/feature.js") }
18
-
19
- it "should include screen definitions" do
20
- should match /SplashScreen = \(function/
21
- end
22
-
23
- it "should include Zucchini runtime" do
24
- should match /Zucchini.run = /
25
- end
26
-
27
- it "should include custom libraries from support/lib" do
28
- should match /Helpers.example = /
29
- end
30
- end
31
- end
32
-
33
- describe "approve" do
34
- subject { lambda { feature.approve "reference" } }
35
-
36
- context "no previous run data" do
37
- before { feature.path = './spec/sample_setup/feature_three' }
38
- it { should raise_error "Directory ./spec/sample_setup/feature_three doesn't contain previous run data" }
39
- end
40
-
41
- context "copies screenshots to reference directory" do
42
- before do
43
- feature.path = './spec/sample_setup/feature_three'
44
- feature.device = {screen: 'retina_ios5'}
45
-
46
- # Copying some random image to run screenshots.
47
- @screenshot_path = "#{feature.path}/run_data/Run\ 1/screenshot.png"
48
- FileUtils.mkdir_p(File.dirname(@screenshot_path))
49
- FileUtils.copy_file("./spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner.png", @screenshot_path)
50
- end
51
-
52
- it "should copy screenshot to reference directory" do
53
- feature.approve "reference"
54
- (File.exists? "#{feature.path}/reference/retina_ios5/screenshot.png").should eq true
55
- end
56
-
57
- it "should copy screenshot to pending directory" do
58
- feature.approve "pending"
59
- (File.exists? "#{feature.path}/pending/retina_ios5/screenshot.png").should eq true
60
- end
61
-
62
- after do
63
- FileUtils.rm_rf("#{feature.path}/run_data")
64
- FileUtils.rm_rf("#{feature.path}/reference")
65
- FileUtils.rm_rf("#{feature.path}/pending")
66
- end
67
- end
68
- end
69
- end
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Zucchini::Generator do
4
- let(:project_path) { "/tmp/z_test_project" }
5
- let(:feature_path) { "#{project_path}/features/rspec_feature" }
6
- let(:generator) { Zucchini::Generator.new(nil) }
7
-
8
- after(:all) { FileUtils.rm_rf(project_path) }
9
-
10
- context "generate a project" do
11
- before { generator.path = project_path }
12
- it "should create a project directory" do
13
- generator.stub!(:project?).and_return(true)
14
- generator.execute
15
- File.exists?("#{project_path}/features/support/config.yml").should be_true
16
- end
17
- end
18
-
19
- context "generate a feature" do
20
- before { generator.path = feature_path }
21
- it "should create a feature directory" do
22
- generator.stub!(:feature?).and_return(true)
23
- generator.execute
24
- File.exists?("#{feature_path}/feature.zucchini").should be_true
25
- end
26
- end
27
- end
@@ -1,31 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Zucchini::Report do
4
- let (:device) { { :name => "iPad 2", :screen => "ipad_ios5", :udid => "rspec012345" } }
5
- let (:feature) do
6
- fake_screenshots = (1..7).to_a.map do |num|
7
- screenshot = Zucchini::Screenshot.new("#{num}.screen_#{num}.png", device)
8
- screenshot.diff = (num > 3) ? [:passed, nil] : [:failed, "120\n"]
9
- screenshot
10
- end
11
-
12
- feature = Zucchini::Feature.new("/my/sample/feature")
13
- feature.device = device
14
- feature.stub!(:screenshots).and_return(fake_screenshots)
15
- feature
16
- end
17
-
18
- let(:html_path) { '/tmp/zucchini_rspec_report.html' }
19
- after { FileUtils.rm(html_path) }
20
-
21
- subject { Zucchini::Report.new([feature], false, html_path) }
22
- before { Zucchini::Report.any_instance.stub(:log) }
23
-
24
- its(:text) { should eq "feature:\n4 passed, 3 failed, 0 pending\n\nFailed:\n 1.screen_1.png: 120\n 2.screen_2.png: 120\n 3.screen_3.png: 120\n" }
25
-
26
- it "should produce a a correct HTML report" do
27
- report = subject.html
28
- report.scan(/<dl class="passed.*screen/).length.should eq 4
29
- report.scan(/<dl class="failed.*screen/).length.should eq 3
30
- end
31
- end
@@ -1,73 +0,0 @@
1
- require 'spec_helper'
2
- require 'digest/md5'
3
-
4
- def md5(blob)
5
- Digest::MD5.hexdigest(blob)
6
- end
7
-
8
- describe Zucchini::Screenshot do
9
- let (:device) { { :name => "iPhone 4S", :screen => "retina_ios5", :udid => "rspec987654" } }
10
- let (:base_path) { "spec/sample_setup/feature_one" }
11
- let (:original_path) { "#{base_path}/run_data/Run\ 1/06_sign\ up_spinner.png" }
12
-
13
- let (:screenshot) do
14
- screenshot = Zucchini::Screenshot.new(original_path, device)
15
- screenshot.masked_paths = { :globally => "#{base_path}/globally_masked.png", :specifically => "#{base_path}/specifically_masked.png" }
16
- screenshot.mask
17
- screenshot
18
- end
19
-
20
- after(:all) do
21
- screenshot.masked_paths.each { |k, path| FileUtils.rm(path) }
22
- FileUtils.rm_rf("#{base_path}/run_data/Masked")
23
- FileUtils.rm_rf(screenshot.diff_path)
24
- end
25
-
26
- describe "mask" do
27
- before(:all) do
28
- @md5 = {
29
- :original => md5(File.read(original_path)),
30
- :globally_masked => md5(File.read(screenshot.masked_paths[:globally])),
31
- :specifically_masked => md5(File.read(screenshot.masked_paths[:specifically]))
32
- }
33
- end
34
-
35
- it "should apply a standard global mask based on the screen" do
36
- File.exists?(screenshot.masked_paths[:globally]).should be true
37
- @md5[:globally_masked].should_not be_equal @md5[:original]
38
- end
39
-
40
- it "should apply a screenshot-specific mask if it exists" do
41
- File.exists?(screenshot.masked_paths[:specifically]).should be true
42
- @md5[:specifically_masked].should_not be_equal @md5[:original]
43
- @md5[:specifically_masked].should_not be_equal @md5[:globally_masked]
44
- end
45
- end
46
-
47
- describe "compare" do
48
- context "images are identical" do
49
- it "should have a passed indicator in the diff" do
50
- screenshot.compare
51
- screenshot.diff.should eq [:passed, nil]
52
- end
53
- end
54
-
55
- context "images are different" do
56
- it "should have a failed indicator in the diff" do
57
- screenshot.stub!(:mask_reference)
58
- screenshot.test_path = "#{base_path}/reference/#{device[:screen]}/06_sign\ up_spinner_error.png"
59
- screenshot.compare
60
- screenshot.diff.should eq [:failed, "3017\n"]
61
- end
62
- end
63
- end
64
-
65
- describe "mask reference" do
66
- it "should create masked versions of reference screenshots" do
67
- screenshot.mask_reference
68
-
69
- File.exists?(screenshot.test_path).should be_true
70
- md5(File.read(screenshot.test_path)).should_not be_equal md5(File.read("#{base_path}/reference/#{device[:screen]}/06_sign\ up_spinner.png"))
71
- end
72
- end
73
- end
@@ -1 +0,0 @@
1
- # Start on the "Splash" screen
@@ -1 +0,0 @@
1
- # Start on the "Menu" screen
@@ -1 +0,0 @@
1
- # Start on the "Menu" screen
@@ -1,16 +0,0 @@
1
- app: MyApp.app
2
-
3
- devices:
4
- My iDevice:
5
- UDID : lolffb28d74a6fraj2156090784avasc50725dd0
6
- screen: ipad_ios5
7
-
8
- Default Device:
9
- screen : low_ios5
10
- default: true
11
-
12
-
13
- servers:
14
- backend:
15
- host: 192.168.1.2
16
- port: 8080
@@ -1,3 +0,0 @@
1
- class Helpers
2
- @example: ->
3
- puts "Helpers.example method is available in your screen classes"
@@ -1,8 +0,0 @@
1
- class SplashScreen extends Screen
2
- anchor: -> view.elements()["Welcome"]
3
-
4
- constructor: ->
5
- super 'splash'
6
-
7
- extend @elements,
8
- 'Go' : -> view.buttons()["Go"]
@@ -1,15 +0,0 @@
1
- app: MyApp.app
2
-
3
- devices:
4
- My iDevice:
5
- UDID : lolffb28d74a6fraj2156090784avasc50725dd0
6
- screen: ipad_ios5
7
-
8
- Default Device:
9
- screen : low_ios5
10
-
11
-
12
- servers:
13
- backend:
14
- host: 192.168.1.2
15
- port: 8080
data/spec/spec_helper.rb DELETED
@@ -1,18 +0,0 @@
1
- require 'clamp'
2
- require 'fileutils'
3
-
4
- $LOAD_PATH << File.expand_path("#{File.dirname(__FILE__)}/..")
5
- require 'lib/config'
6
- require 'lib/screenshot'
7
- require 'lib/report'
8
- require 'lib/feature'
9
- require 'lib/detector'
10
- require 'lib/runner'
11
- require 'lib/generator'
12
- require 'lib/approver'
13
-
14
- RSpec.configure do |config|
15
- config.color_enabled = true
16
- config.tty = true
17
- #config.formatter = :documentation
18
- end
data/zucchini-ios.gemspec DELETED
@@ -1,27 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require 'version'
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "zucchini-ios"
7
- s.version = Zucchini::VERSION
8
- s.date = Date.today.to_s
9
- s.platform = Gem::Platform::RUBY
10
- s.authors = ["Vasily Mikhaylichenko", "Rajesh Kumar", "Kevin O'Neill"]
11
- s.license = "BSD"
12
- s.email = ["vaskas@zucchiniframework.org"]
13
- s.homepage = "http://www.zucchiniframework.org"
14
- s.summary = %q{Functional testing framework for iOS-powered devices}
15
- s.description = %q{Zucchini follows simple walkthrough scenarios for your iOS app, takes screenshots and compares them to the reference ones.}
16
-
17
- s.add_runtime_dependency "clamp"
18
- s.add_development_dependency "rspec"
19
- s.add_development_dependency "watchr"
20
-
21
- s.files = `git ls-files | grep -vE '(web|.watchr)'`.split("\n")
22
- s.test_files = `git ls-files -- spec/*`.split("\n")
23
- s.executables = %w(zucchini)
24
- s.require_paths = ["lib"]
25
-
26
- s.required_ruby_version = '>= 1.9.2'
27
- end