zucchini-ios 0.5.7 → 0.5.8

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE.md ADDED
@@ -0,0 +1,8 @@
1
+ Copyright (c) Vasily Mikhaylichenko and PlayUp USA, LLC.
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
+
5
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
7
+
8
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md CHANGED
@@ -8,7 +8,8 @@ Pre-requisites
8
8
  4. A few command line tools:
9
9
 
10
10
  ```
11
- brew update && brew install imagemagick && brew install coffee-script
11
+ brew update && brew install imagemagick node
12
+ npm install -g coffee-script
12
13
  ```
13
14
 
14
15
  Start using Zucchini
data/bin/zucchini CHANGED
@@ -8,12 +8,15 @@ require 'lib/config'
8
8
  require 'lib/screenshot'
9
9
  require 'lib/report'
10
10
  require 'lib/feature'
11
+ require 'lib/detector'
11
12
  require 'lib/runner'
12
13
  require 'lib/generator'
14
+ require 'lib/approver'
13
15
 
14
16
  class Zucchini::App < Clamp::Command
15
17
  subcommand "generate", "Generate a project scaffold", Zucchini::Generator
16
18
  subcommand "run", "Run zucchini", Zucchini::Runner
19
+ subcommand "approve", "Update reference screenshots", Zucchini::Approver
17
20
  end
18
21
 
19
22
  Zucchini::App.run
data/lib/approver.rb ADDED
@@ -0,0 +1,14 @@
1
+ class Zucchini::Approver < Zucchini::Detector
2
+ parameter "PATH", "a path to feature or a directory"
3
+
4
+ option %W(-p --pending), :flag, "update pending screenshots instead"
5
+
6
+ def run_command
7
+ reference_type = pending? ? "pending" : "reference"
8
+ features.each do |f|
9
+ f.device = @device
10
+ f.approve reference_type
11
+ end
12
+ features.inject(true){ |result, feature| result &= feature.succeeded }
13
+ end
14
+ end
data/lib/detector.rb ADDED
@@ -0,0 +1,61 @@
1
+ class Zucchini::Detector < Clamp::Command
2
+ attr_reader :features
3
+
4
+ parameter "PATH", "a path to feature or a directory"
5
+
6
+ def execute
7
+ raise "Directory #{path} does not exist" unless File.exists?(path)
8
+
9
+ @path = File.expand_path(path)
10
+ Zucchini::Config.base_path = File.exists?("#{path}/feature.zucchini") ? File.dirname(path) : path
11
+
12
+ raise "ZUCCHINI_DEVICE environment variable not set" unless ENV['ZUCCHINI_DEVICE']
13
+ @device = Zucchini::Config.device(ENV['ZUCCHINI_DEVICE'])
14
+
15
+ @template = detect_template
16
+
17
+ exit run_command
18
+ end
19
+
20
+ def run_command; end
21
+
22
+ def features
23
+ @features ||= detect_features(@path)
24
+ end
25
+
26
+ def detect_features(path)
27
+ features = []
28
+ if File.exists?("#{path}/feature.zucchini")
29
+ features << Zucchini::Feature.new(path)
30
+ else
31
+ raise detection_error(path) if Dir["#{path}/*"].empty?
32
+
33
+ Dir.glob("#{path}/*").each do |dir|
34
+ unless dir.match /support/
35
+ if File.exists?("#{dir}/feature.zucchini")
36
+ features << Zucchini::Feature.new(dir)
37
+ else
38
+ raise detection_error(dir)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ features
44
+ end
45
+
46
+ def detection_error(path)
47
+ "#{path} is not a feature directory"
48
+ end
49
+
50
+ def detect_template
51
+ locations = [
52
+ `xcode-select -print-path`.gsub(/\n/, '') + "/Platforms/iPhoneOS.platform/Developer/Library/Instruments",
53
+ "/Applications/Xcode.app/Contents/Applications/Instruments.app/Contents" # Xcode 4.5
54
+ ].map do |start_path|
55
+ "#{start_path}/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate"
56
+ end
57
+
58
+ locations.each { |path| return path if File.exists?(path) }
59
+ raise "Can't find Instruments template (tried #{locations.join(', ')})"
60
+ end
61
+ end
data/lib/feature.rb CHANGED
@@ -27,11 +27,13 @@ class Zucchini::Feature
27
27
  end
28
28
  end
29
29
 
30
- def screenshots
30
+ def screenshots(process = true)
31
31
  @screenshots ||= Dir.glob("#{run_data_path}/Run\ 1/*.png").map do |file|
32
32
  screenshot = Zucchini::Screenshot.new(file, @device)
33
- screenshot.mask
34
- screenshot.compare
33
+ if process
34
+ screenshot.mask
35
+ screenshot.compare
36
+ end
35
37
  screenshot
36
38
  end + unmatched_pending_screenshots
37
39
  end
@@ -92,4 +94,14 @@ class Zucchini::Feature
92
94
  yield
93
95
  end
94
96
  end
97
+
98
+ def approve(reference_type)
99
+ raise "Directory #{path} doesn't contain previous run data" unless File.exists?("#{run_data_path}/Run\ 1")
100
+
101
+ screenshots(false).each do |s|
102
+ reference_file_path = "#{File.dirname(s.file_path)}/../../#{reference_type}/#{device[:screen]}/#{s.file_name}"
103
+ FileUtils.mkdir_p File.dirname(reference_file_path)
104
+ @succeeded = FileUtils.copy_file(s.file_path, reference_file_path)
105
+ end
106
+ end
95
107
  end
data/lib/runner.rb CHANGED
@@ -1,7 +1,5 @@
1
- class Zucchini::Runner < Clamp::Command
2
- attr_reader :features
3
-
4
- parameter "PATH", "a path to feature or a directory to run"
1
+ class Zucchini::Runner < Zucchini::Detector
2
+ parameter "PATH", "a path to feature or a directory"
5
3
 
6
4
  option %W(-c --collect), :flag, "only collect the screenshots from the device"
7
5
  option %W(-p --compare), :flag, "perform screenshots comparison based on the last collection"
@@ -9,21 +7,7 @@ class Zucchini::Runner < Clamp::Command
9
7
 
10
8
  option "--ci", :flag, "produce a CI version of the report after comparison"
11
9
 
12
- def execute
13
- raise "Directory #{path} does not exist" unless File.exists?(path)
14
-
15
- @path = File.expand_path(path)
16
- Zucchini::Config.base_path = File.exists?("#{path}/feature.zucchini") ? File.dirname(path) : path
17
-
18
- raise "ZUCCHINI_DEVICE environment variable not set" unless ENV['ZUCCHINI_DEVICE']
19
- @device = Zucchini::Config.device(ENV['ZUCCHINI_DEVICE'])
20
-
21
- @template = detect_template
22
-
23
- exit run_features
24
- end
25
-
26
- def run_features
10
+ def run_command
27
11
  compare_threads = {}
28
12
 
29
13
  features.each do |f|
@@ -45,44 +29,4 @@ class Zucchini::Runner < Clamp::Command
45
29
 
46
30
  features.inject(true){ |result, feature| result &= feature.succeeded }
47
31
  end
48
-
49
- def features
50
- @features ||= detect_features(@path)
51
- end
52
-
53
- def detect_features(path)
54
- features = []
55
- if File.exists?("#{path}/feature.zucchini")
56
- features << Zucchini::Feature.new(path)
57
- else
58
- raise detection_error(path) if Dir["#{path}/*"].empty?
59
-
60
- Dir.glob("#{path}/*").each do |dir|
61
- unless dir.match /support/
62
- if File.exists?("#{dir}/feature.zucchini")
63
- features << Zucchini::Feature.new(dir)
64
- else
65
- raise detection_error(dir)
66
- end
67
- end
68
- end
69
- end
70
- features
71
- end
72
-
73
- def detection_error(path)
74
- "#{path} is not a feature directory"
75
- end
76
-
77
- def detect_template
78
- locations = [
79
- `xcode-select -print-path`.gsub(/\n/, '') + "/Platforms/iPhoneOS.platform/Developer/Library/Instruments",
80
- "/Applications/Xcode.app/Contents/Applications/Instruments.app/Contents" # Xcode 4.5
81
- ].map do |start_path|
82
- "#{start_path}/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate"
83
- end
84
-
85
- locations.each { |path| return path if File.exists?(path) }
86
- raise "Can't find Instruments template (tried #{locations.join(', ')})"
87
- end
88
32
  end
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Zucchini
2
- VERSION = "0.5.7"
2
+ VERSION = "0.5.8"
3
3
  end
@@ -1,29 +1,29 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Zucchini::Runner do
4
- before (:each) do
5
- runner.path = "spec/sample_setup/feature_one"
3
+ describe Zucchini::Detector do
4
+ before do
5
+ detector.path = "spec/sample_setup/feature_one"
6
6
  ENV['ZUCCHINI_DEVICE'] = 'My iDevice'
7
7
  end
8
8
 
9
- let (:runner) { Zucchini::Runner.new(nil) }
10
-
9
+ let (:detector) { Zucchini::Detector.new(nil) }
10
+
11
11
  describe "execute" do
12
- subject { lambda { runner.execute } }
12
+ subject { lambda { detector.execute } }
13
13
 
14
14
  context "feature directory doesn't exist" do
15
- before { runner.path = "spec/sample_setup/erroneous_feature" }
15
+ before { detector.path = "spec/sample_setup/erroneous_feature" }
16
16
  it { should raise_error "Directory spec/sample_setup/erroneous_feature does not exist" }
17
17
  end
18
-
18
+
19
19
  context "device hasn't been found" do
20
20
  before { ENV['ZUCCHINI_DEVICE'] = 'My Android Phone' }
21
21
  it { should raise_error "Device not listed in config.yml" }
22
22
  end
23
23
  end
24
-
24
+
25
25
  describe "detect features" do
26
- subject { lambda { runner.detect_features(@path) } }
26
+ subject { lambda { detector.detect_features(@path) } }
27
27
 
28
28
  context "path to a single feature" do
29
29
  before { @path = "spec/sample_setup/feature_one" }
@@ -35,7 +35,7 @@ describe Zucchini::Runner do
35
35
  context "path to a directory with features" do
36
36
  before { @path = File.expand_path("spec/sample_setup") }
37
37
  it "should detect all features in it" do
38
- subject.call.length.should eq 2
38
+ subject.call.length.should eq 3
39
39
  end
40
40
  end
41
41
 
@@ -29,4 +29,41 @@ describe Zucchini::Feature do
29
29
  end
30
30
  end
31
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
32
69
  end
@@ -0,0 +1 @@
1
+ # Start on the "Menu" screen
data/spec/spec_helper.rb CHANGED
@@ -6,8 +6,10 @@ require 'lib/config'
6
6
  require 'lib/screenshot'
7
7
  require 'lib/report'
8
8
  require 'lib/feature'
9
+ require 'lib/detector'
9
10
  require 'lib/runner'
10
11
  require 'lib/generator'
12
+ require 'lib/approver'
11
13
 
12
14
  RSpec.configure do |config|
13
15
  config.color_enabled = true
data/zucchini-ios.gemspec CHANGED
@@ -8,6 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.date = Date.today.to_s
9
9
  s.platform = Gem::Platform::RUBY
10
10
  s.authors = ["Vasily Mikhaylichenko", "Rajesh Kumar", "Kevin O'Neill"]
11
+ s.license = "BSD"
11
12
  s.email = ["vaskas@zucchiniframework.org"]
12
13
  s.homepage = "http://www.zucchiniframework.org"
13
14
  s.summary = %q{Functional testing framework for iOS-powered devices}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zucchini-ios
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.7
4
+ version: 0.5.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-12-17 00:00:00.000000000 Z
14
+ date: 2013-02-03 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: clamp
@@ -74,10 +74,13 @@ files:
74
74
  - .travis.yml
75
75
  - Gemfile
76
76
  - Gemfile.lock
77
+ - LICENSE.md
77
78
  - README.md
78
79
  - Rakefile
79
80
  - bin/zucchini
81
+ - lib/approver.rb
80
82
  - lib/config.rb
83
+ - lib/detector.rb
81
84
  - lib/feature.rb
82
85
  - lib/generator.rb
83
86
  - lib/report.rb
@@ -94,16 +97,17 @@ files:
94
97
  - lib/uia/screen.coffee
95
98
  - lib/version.rb
96
99
  - spec/lib/config_spec.rb
100
+ - spec/lib/detector_spec.rb
97
101
  - spec/lib/feature_spec.rb
98
102
  - spec/lib/generator_spec.rb
99
103
  - spec/lib/report_spec.rb
100
- - spec/lib/runner_spec.rb
101
104
  - spec/lib/screenshot_spec.rb
102
105
  - spec/sample_setup/feature_one/feature.zucchini
103
106
  - spec/sample_setup/feature_one/masks/retina_ios5/06_sign up_spinner.png
104
107
  - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner.png
105
108
  - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner_error.png
106
109
  - spec/sample_setup/feature_one/run_data/Run 1/06_sign up_spinner.png
110
+ - spec/sample_setup/feature_three/feature.zucchini
107
111
  - spec/sample_setup/feature_two/feature.zucchini
108
112
  - spec/sample_setup/feature_two/masks/retina_ios5/06_sign up_spinner.png
109
113
  - spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner.png
@@ -128,7 +132,8 @@ files:
128
132
  - templates/project/features/support/screens/welcome.coffee
129
133
  - zucchini-ios.gemspec
130
134
  homepage: http://www.zucchiniframework.org
131
- licenses: []
135
+ licenses:
136
+ - BSD
132
137
  post_install_message:
133
138
  rdoc_options: []
134
139
  require_paths:
@@ -147,22 +152,23 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
152
  version: '0'
148
153
  requirements: []
149
154
  rubyforge_project:
150
- rubygems_version: 1.8.24
155
+ rubygems_version: 1.8.23
151
156
  signing_key:
152
157
  specification_version: 3
153
158
  summary: Functional testing framework for iOS-powered devices
154
159
  test_files:
155
160
  - spec/lib/config_spec.rb
161
+ - spec/lib/detector_spec.rb
156
162
  - spec/lib/feature_spec.rb
157
163
  - spec/lib/generator_spec.rb
158
164
  - spec/lib/report_spec.rb
159
- - spec/lib/runner_spec.rb
160
165
  - spec/lib/screenshot_spec.rb
161
166
  - spec/sample_setup/feature_one/feature.zucchini
162
167
  - spec/sample_setup/feature_one/masks/retina_ios5/06_sign up_spinner.png
163
168
  - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner.png
164
169
  - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner_error.png
165
170
  - spec/sample_setup/feature_one/run_data/Run 1/06_sign up_spinner.png
171
+ - spec/sample_setup/feature_three/feature.zucchini
166
172
  - spec/sample_setup/feature_two/feature.zucchini
167
173
  - spec/sample_setup/feature_two/masks/retina_ios5/06_sign up_spinner.png
168
174
  - spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner.png