zucchini-ios 0.5.3

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.
Files changed (50) hide show
  1. data/README.md +51 -0
  2. data/bin/zucchini +19 -0
  3. data/lib/config.rb +51 -0
  4. data/lib/feature.rb +87 -0
  5. data/lib/generator.rb +18 -0
  6. data/lib/report/css/zucchini.report.css +239 -0
  7. data/lib/report/js/jquery.effects.core.js +31 -0
  8. data/lib/report/js/jquery.js +4 -0
  9. data/lib/report/js/jquery.ui.core.js +18 -0
  10. data/lib/report/js/zucchini.report.js +59 -0
  11. data/lib/report/template.erb +47 -0
  12. data/lib/report/view.rb +16 -0
  13. data/lib/report.rb +30 -0
  14. data/lib/runner.rb +67 -0
  15. data/lib/screenshot.rb +82 -0
  16. data/lib/uia/base.coffee +63 -0
  17. data/lib/uia/screen.coffee +21 -0
  18. data/lib/version.rb +3 -0
  19. data/spec/lib/config_spec.rb +25 -0
  20. data/spec/lib/generator_spec.rb +27 -0
  21. data/spec/lib/report_spec.rb +34 -0
  22. data/spec/lib/runner_spec.rb +52 -0
  23. data/spec/lib/screenshot_spec.rb +73 -0
  24. data/spec/sample_setup/feature_one/feature.zucchini +1 -0
  25. data/spec/sample_setup/feature_one/masks/retina_ios5/06_sign up_spinner.png +0 -0
  26. data/spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner.png +0 -0
  27. data/spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner_error.png +0 -0
  28. data/spec/sample_setup/feature_one/run_data/Run 1/06_sign up_spinner.png +0 -0
  29. data/spec/sample_setup/feature_two/feature.zucchini +1 -0
  30. data/spec/sample_setup/feature_two/masks/retina_ios5/06_sign up_spinner.png +0 -0
  31. data/spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner.png +0 -0
  32. data/spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner_error.png +0 -0
  33. data/spec/sample_setup/feature_two/run_data/Run 1/06_sign up_spinner.png +0 -0
  34. data/spec/sample_setup/support/config.yml +13 -0
  35. data/spec/sample_setup/support/masks/retina_ios5.png +0 -0
  36. data/spec/sample_setup/support/screens/splash.coffee +8 -0
  37. data/spec/spec_helper.rb +16 -0
  38. data/templates/feature/feature.zucchini +6 -0
  39. data/templates/feature/masks/retina_ios5/.gitkeep +0 -0
  40. data/templates/feature/pending/retina_ios5/.gitkeep +0 -0
  41. data/templates/feature/reference/retina_ios5/.gitkeep +0 -0
  42. data/templates/feature/run_data/.gitignore +5 -0
  43. data/templates/feature/setup.rb +10 -0
  44. data/templates/project/features/support/config.yml +13 -0
  45. data/templates/project/features/support/masks/ipad_ios5.png +0 -0
  46. data/templates/project/features/support/masks/low_ios4.png +0 -0
  47. data/templates/project/features/support/masks/retina_ios5.png +0 -0
  48. data/templates/project/features/support/screens/welcome.coffee +13 -0
  49. data/zucchini.gemspec +24 -0
  50. metadata +155 -0
@@ -0,0 +1,63 @@
1
+ Function::bind = (context) ->
2
+ return this unless context
3
+ fun = this
4
+ ->
5
+ fun.apply context, arguments
6
+
7
+ String::camelCase = ->
8
+ @replace /([\-\ ][A-Za-z])/g, ($1) ->
9
+ $1.toUpperCase().replace /[\-\ ]/g, ""
10
+
11
+ extend = (obj, mixin) ->
12
+ obj[name] = method for name, method of mixin
13
+ obj
14
+
15
+ puts = (text) ->
16
+ UIALogger.logMessage text
17
+
18
+ target = UIATarget.localTarget()
19
+ view = target.frontMostApp().mainWindow()
20
+
21
+ target.waitForElement = (element) ->
22
+ return unless element
23
+ found = false
24
+ counter = 0
25
+ while not found and (counter < 10)
26
+ if element.isValid() and element.isVisible()
27
+ found = true
28
+ puts "Got the awaited element: #{element}"
29
+ @delay 1
30
+ else
31
+ @delay 0.5
32
+ counter++
33
+
34
+ screensCount = 0
35
+ target.captureScreenWithName_ = target.captureScreenWithName
36
+ target.captureScreenWithName = (screenName) ->
37
+ screensCountText = (if (++screensCount < 10) then "0" + screensCount else screensCount)
38
+ @captureScreenWithName_ screensCountText + "_" + screenName
39
+
40
+ class Zucchini
41
+ @run: (featureText) ->
42
+ sections = featureText.trim().split(/\n\s*\n/)
43
+
44
+ for section in sections
45
+ lines = section.split(/\n/)
46
+
47
+ screenMatch = lines[0].match(/.+ on the "([^"]*)" screen:$/)
48
+ throw "Line '#{lines[0]}' doesn't define a screen context" unless screenMatch
49
+
50
+ screenName = screenMatch[1]
51
+ try
52
+ screen = eval("new #{screenName.camelCase()}Screen")
53
+ catch error
54
+ throw "Screen '#{screenName}' not defined"
55
+
56
+ for line in lines.slice(1)
57
+ functionFound = false
58
+ for regExpText, func of screen.actions
59
+ match = line.trim().match(new RegExp(regExpText))
60
+ if match
61
+ functionFound = true
62
+ func.bind(screen)(match[1])
63
+ throw "Action for line '#{line}' not defined" unless functionFound
@@ -0,0 +1,21 @@
1
+ class Screen
2
+ constructor: (@name) ->
3
+ if @anchor then target.waitForElement @anchor()
4
+
5
+ elements: {}
6
+ actions :
7
+ 'Take a screenshot$' : ->
8
+ target.captureScreenWithName(@name)
9
+
10
+ 'Take a screenshot named "([^"]*)"$' : (name) ->
11
+ target.captureScreenWithName(name)
12
+
13
+ 'Tap "([^"]*)"$' : (element) ->
14
+ throw "Element '#{element}' not defined for the screen '#{@name}'" unless @elements[element]
15
+ @elements[element]().tap()
16
+
17
+ 'Wait for "([^"]*)" second[s]*$' : (seconds) ->
18
+ target.delay(seconds)
19
+
20
+ 'Confirm "([^"]*)"$' : (element) ->
21
+ @actions['Tap "([^"]*)"$'].bind(this)(element)
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Zucchini
2
+ VERSION = "0.5.3"
3
+ end
@@ -0,0 +1,25 @@
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
+ end
19
+
20
+ describe "url" do
21
+ it "should return a full URL string for a given server name" do
22
+ Zucchini::Config.url('backend', '/api').should eq "http://192.168.1.2:8080/api"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
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
@@ -0,0 +1,34 @@
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
+ describe "text" do
19
+ it "should return the correct summary text" do
20
+ Zucchini::Report.text([feature]).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"
21
+ end
22
+ end
23
+
24
+ describe "HTML" do
25
+ let(:report_html_path) { "/tmp/zucchini_rspec_report.html" }
26
+ after { FileUtils.rm(report_html_path) }
27
+
28
+ it "should produce a a correct HTML report" do
29
+ report = File.open(Zucchini::Report.html([feature], false, report_html_path)).read
30
+ report.scan(/<dl class="passed.*screen/).length.should eq 4
31
+ report.scan(/<dl class="failed.*screen/).length.should eq 3
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe Zucchini::Runner do
4
+ before (:each) do
5
+ runner.path = "spec/sample_setup/feature_one"
6
+ ENV['ZUCCHINI_DEVICE'] = 'My iDevice'
7
+ end
8
+
9
+ let (:runner) { Zucchini::Runner.new(nil) }
10
+
11
+ describe "execute" do
12
+ subject { lambda { runner.execute } }
13
+
14
+ context "feature directory doesn't exist" do
15
+ before { runner.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 { runner.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 2
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
@@ -0,0 +1,73 @@
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
@@ -0,0 +1 @@
1
+ # Start on the "Splash" screen
@@ -0,0 +1 @@
1
+ # Start on the "Menu" screen
@@ -0,0 +1,13 @@
1
+ app: MyApp.app
2
+ template: '/Developer/Platforms/iPhoneOS.platform/Developer/Library/Instruments/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate'
3
+
4
+ devices:
5
+ My iDevice:
6
+ UDID : lolffb28d74a6fraj2156090784avasc50725dd0
7
+ screen: ipad_ios5
8
+
9
+
10
+ servers:
11
+ backend:
12
+ host: 192.168.1.2
13
+ port: 8080
@@ -0,0 +1,8 @@
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"]
@@ -0,0 +1,16 @@
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/runner'
10
+ require 'lib/generator'
11
+
12
+ RSpec.configure do |config|
13
+ config.color_enabled = true
14
+ config.tty = true
15
+ #config.formatter = :documentation
16
+ end
@@ -0,0 +1,6 @@
1
+ # Start on the "Welcome" screen:
2
+ # Take a screenshot named "welcome_first_boot"
3
+ # Type "Zucchini" in the username field
4
+ # Tap "Go"
5
+
6
+
File without changes
File without changes
File without changes
@@ -0,0 +1,5 @@
1
+ feature.*
2
+ report.html
3
+ Run\ *
4
+ Diff/
5
+ Masked/
@@ -0,0 +1,10 @@
1
+ class Setup
2
+ def self.before
3
+ # do useful stuff
4
+ yield
5
+ end
6
+
7
+ def self.after
8
+ # clean up
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ app: MyApp.app
2
+ template: '/Developer/Platforms/iPhoneOS.platform/Developer/Library/Instruments/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate'
3
+
4
+ devices:
5
+ My iDevice:
6
+ UDID : lolffb28d74a6fraj2156090784avasc50725dd0
7
+ screen: retina_ios5
8
+
9
+
10
+ servers:
11
+ backend:
12
+ host: 192.168.1.2
13
+ port: 8080
@@ -0,0 +1,13 @@
1
+ class WelcomeScreen extends Screen
2
+ anchor: -> view.elements()["Welcome to MyApp"]
3
+
4
+ constructor: ->
5
+ super 'welcome'
6
+
7
+ extend @elements,
8
+ 'Go' : -> view.buttons()["Go"]
9
+
10
+ extend @actions,
11
+ 'Type "([^"]*)" in the username field$': (text) ->
12
+ field = view.elements()['Username']
13
+ field.setValue text
data/zucchini.gemspec ADDED
@@ -0,0 +1,24 @@
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.email = ["vasily@playup.com"]
12
+ s.homepage = "http://www.zucchiniframework.org"
13
+ s.summary = %q{Functional testing framework for iOS-powered devices}
14
+ s.description = %q{Zucchini follows simple walkthrough scenarios for your iOS app, takes screenshots and compares them to the reference ones.}
15
+
16
+ s.add_runtime_dependency "clamp"
17
+ s.add_development_dependency "rspec"
18
+ s.add_development_dependency "watchr"
19
+
20
+ s.files = `git ls-files | grep -vE '(web|.watchr)'`.split("\n")
21
+ s.test_files = `git ls-files -- spec/*`.split("\n")
22
+ s.executables = %w(zucchini)
23
+ s.require_paths = ["lib"]
24
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zucchini-ios
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.5.3
6
+ platform: ruby
7
+ authors:
8
+ - Vasily Mikhaylichenko
9
+ - Rajesh Kumar
10
+ - Kevin O'Neill
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+
15
+ date: 2011-12-22 00:00:00 Z
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: clamp
19
+ prerelease: false
20
+ requirement: &id001 !ruby/object:Gem::Requirement
21
+ none: false
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: "0"
26
+ type: :runtime
27
+ version_requirements: *id001
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ prerelease: false
31
+ requirement: &id002 !ruby/object:Gem::Requirement
32
+ none: false
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: "0"
37
+ type: :development
38
+ version_requirements: *id002
39
+ - !ruby/object:Gem::Dependency
40
+ name: watchr
41
+ prerelease: false
42
+ requirement: &id003 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ type: :development
49
+ version_requirements: *id003
50
+ description: Zucchini follows simple walkthrough scenarios for your iOS app, takes screenshots and compares them to the reference ones.
51
+ email:
52
+ - vasily@playup.com
53
+ executables:
54
+ - zucchini
55
+ extensions: []
56
+
57
+ extra_rdoc_files: []
58
+
59
+ files:
60
+ - README.md
61
+ - bin/zucchini
62
+ - lib/config.rb
63
+ - lib/feature.rb
64
+ - lib/generator.rb
65
+ - lib/report.rb
66
+ - lib/report/css/zucchini.report.css
67
+ - lib/report/js/jquery.effects.core.js
68
+ - lib/report/js/jquery.js
69
+ - lib/report/js/jquery.ui.core.js
70
+ - lib/report/js/zucchini.report.js
71
+ - lib/report/template.erb
72
+ - lib/report/view.rb
73
+ - lib/runner.rb
74
+ - lib/screenshot.rb
75
+ - lib/uia/base.coffee
76
+ - lib/uia/screen.coffee
77
+ - lib/version.rb
78
+ - spec/lib/config_spec.rb
79
+ - spec/lib/generator_spec.rb
80
+ - spec/lib/report_spec.rb
81
+ - spec/lib/runner_spec.rb
82
+ - spec/lib/screenshot_spec.rb
83
+ - spec/sample_setup/feature_one/feature.zucchini
84
+ - spec/sample_setup/feature_one/masks/retina_ios5/06_sign up_spinner.png
85
+ - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner.png
86
+ - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner_error.png
87
+ - spec/sample_setup/feature_one/run_data/Run 1/06_sign up_spinner.png
88
+ - spec/sample_setup/feature_two/feature.zucchini
89
+ - spec/sample_setup/feature_two/masks/retina_ios5/06_sign up_spinner.png
90
+ - spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner.png
91
+ - spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner_error.png
92
+ - spec/sample_setup/feature_two/run_data/Run 1/06_sign up_spinner.png
93
+ - spec/sample_setup/support/config.yml
94
+ - spec/sample_setup/support/masks/retina_ios5.png
95
+ - spec/sample_setup/support/screens/splash.coffee
96
+ - spec/spec_helper.rb
97
+ - templates/feature/feature.zucchini
98
+ - templates/feature/masks/retina_ios5/.gitkeep
99
+ - templates/feature/pending/retina_ios5/.gitkeep
100
+ - templates/feature/reference/retina_ios5/.gitkeep
101
+ - templates/feature/run_data/.gitignore
102
+ - templates/feature/setup.rb
103
+ - templates/project/features/support/config.yml
104
+ - templates/project/features/support/masks/ipad_ios5.png
105
+ - templates/project/features/support/masks/low_ios4.png
106
+ - templates/project/features/support/masks/retina_ios5.png
107
+ - templates/project/features/support/screens/welcome.coffee
108
+ - zucchini.gemspec
109
+ homepage: http://www.zucchiniframework.org
110
+ licenses: []
111
+
112
+ post_install_message:
113
+ rdoc_options: []
114
+
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: "0"
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: "0"
129
+ requirements: []
130
+
131
+ rubyforge_project:
132
+ rubygems_version: 1.8.12
133
+ signing_key:
134
+ specification_version: 3
135
+ summary: Functional testing framework for iOS-powered devices
136
+ test_files:
137
+ - spec/lib/config_spec.rb
138
+ - spec/lib/generator_spec.rb
139
+ - spec/lib/report_spec.rb
140
+ - spec/lib/runner_spec.rb
141
+ - spec/lib/screenshot_spec.rb
142
+ - spec/sample_setup/feature_one/feature.zucchini
143
+ - spec/sample_setup/feature_one/masks/retina_ios5/06_sign up_spinner.png
144
+ - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner.png
145
+ - spec/sample_setup/feature_one/reference/retina_ios5/06_sign up_spinner_error.png
146
+ - spec/sample_setup/feature_one/run_data/Run 1/06_sign up_spinner.png
147
+ - spec/sample_setup/feature_two/feature.zucchini
148
+ - spec/sample_setup/feature_two/masks/retina_ios5/06_sign up_spinner.png
149
+ - spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner.png
150
+ - spec/sample_setup/feature_two/reference/retina_ios5/06_sign up_spinner_error.png
151
+ - spec/sample_setup/feature_two/run_data/Run 1/06_sign up_spinner.png
152
+ - spec/sample_setup/support/config.yml
153
+ - spec/sample_setup/support/masks/retina_ios5.png
154
+ - spec/sample_setup/support/screens/splash.coffee
155
+ - spec/spec_helper.rb