lesspainful 0.8.0 → 0.9.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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ test/ipa/vendor
2
+ test/vendor
3
+ vendor
4
+ pkg
5
+ .idea
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lesspainful (0.0.2)
4
+ lesspainful (0.9.0)
5
5
  bundler (~> 1.2)
6
6
  json
7
7
  rest-client
8
+ rubyzip
8
9
 
9
10
  GEM
10
11
  remote: http://rubygems.org/
@@ -13,6 +14,7 @@ GEM
13
14
  mime-types (1.19)
14
15
  rest-client (1.6.7)
15
16
  mime-types (>= 1.16)
17
+ rubyzip (0.9.9)
16
18
 
17
19
  PLATFORMS
18
20
  ruby
data/bin/lesspainful CHANGED
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'zip/zip'
2
4
  require 'digest'
3
5
  require 'rest_client'
4
6
  require 'json'
5
7
  require 'rbconfig'
8
+ require 'tmpdir'
6
9
 
7
10
  def host
8
11
  ENV["LP_HOST"] || "https://www.lesspainful.com"
@@ -12,14 +15,36 @@ def digest(file)
12
15
  Digest::SHA256.file(file).hexdigest
13
16
  end
14
17
 
18
+ def unzip_file (file, destination)
19
+ Zip::ZipFile.open(File.new(file)) { |zip_file|
20
+ zip_file.each { |f|
21
+ f_path=File.join(destination, f.name)
22
+ FileUtils.mkdir_p(File.dirname(f_path))
23
+ zip_file.extract(f, f_path) unless File.exist?(f_path)
24
+ }
25
+ }
26
+ end
27
+
15
28
  def workspace
16
29
  if ARGV[2]
17
- "#{ARGV[2]}/"
30
+ abort_unless(File.exist?(ARGV[2])) do
31
+ puts "Provided workspace: #{ARGV[2]} does not exist."
32
+ end
33
+ File.join(File.expand_path(ARGV[2]),File::Separator)
18
34
  else
19
35
  ""
20
36
  end
21
37
  end
22
38
 
39
+ def features_zip
40
+ if ARGV[3] and ARGV[3].end_with?".zip"
41
+ abort_unless(File.exist?(ARGV[3])) do
42
+ puts "No file found #{ARGV[3]}"
43
+ end
44
+ File.expand_path(ARGV[3])
45
+ end
46
+ end
47
+
23
48
  def app
24
49
  ARGV[0]
25
50
  end
@@ -36,19 +61,30 @@ def calabash_android_version
36
61
  `bundle exec calabash-android version`.strip
37
62
  end
38
63
 
64
+ def is_ios?
65
+ app.end_with? ".ipa"
66
+ end
67
+
39
68
  def test_server_path
40
69
  require 'digest/md5'
41
70
  digest = Digest::MD5.hexdigest(File.read(app))
42
- "#{workspace}test_servers/#{digest}_#{calabash_android_version}.apk"
71
+ File.join(workspace,"test_servers","#{digest}_#{calabash_android_version}.apk")
43
72
  end
44
73
 
45
74
  def all_files
46
- files = Dir.glob("#{workspace}features/**/*")
75
+ dir = workspace
76
+ if features_zip
77
+ dir = Dir.mktmpdir
78
+ unzip_file(features_zip, dir)
79
+ dir = File.join(dir,File::Separator)
80
+ end
81
+
82
+ files = Dir.glob("#{dir}features/**/*") ##no need to File.join here
47
83
  files += Dir.glob("#{workspace}vendor/**/*")
48
84
  if is_android?
49
85
  files << test_server_path
50
86
  end
51
- files.find_all { |file_or_dir| File.file? file_or_dir }
87
+ {:prefix => dir, :files => files.find_all { |file_or_dir| File.file? file_or_dir }}
52
88
  end
53
89
 
54
90
  def http_post(address, args)
@@ -60,6 +96,41 @@ def is_windows?
60
96
  (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
61
97
  end
62
98
 
99
+ def is_macosx?
100
+ (RbConfig::CONFIG['host_os'] =~ /darwin/)
101
+ end
102
+
103
+ def validate_ipa(ipa)
104
+ result = true
105
+ dir = Dir.mktmpdir #do |dir|
106
+
107
+ unzip_file(ipa,dir)
108
+ unless File.directory?("#{dir}/Payload") #macos only
109
+ abort do
110
+ puts "Unzipping #{ipa} to #{dir} failed: Did not find a Payload directory (invalid .ipa)."
111
+ end
112
+ end
113
+ app_dir = Dir.foreach("#{dir}/Payload").find {|d| /\.app$/.match(d)}
114
+ app = app_dir.split(".")[0]
115
+ res = `otool "#{File.expand_path(dir)}/Payload/#{app_dir}/#{app}" -o 2> /dev/null | grep CalabashServer`
116
+
117
+ if /CalabashServer/.match(res)
118
+ puts "ipa: #{ipa} *contains* calabash.framework"
119
+ result = :calabash
120
+ end
121
+ res = `otool "#{File.expand_path(dir)}/Payload/#{app_dir}/#{app}" -o 2> /dev/null | grep FrankServer`
122
+ if /FrankServer/.match(res)
123
+ puts "ipa: #{ipa} *contains* FrankServer"
124
+ result = :frank
125
+ else
126
+ puts "ipa: #{ipa} *does not contain* calabash.framework"
127
+ result = false
128
+ end
129
+ #end
130
+ result
131
+ end
132
+
133
+
63
134
  def self.log(message)
64
135
  puts "#{Time.now } #{message}"
65
136
  $stdout.flush
@@ -73,20 +144,32 @@ def self.log_header(message)
73
144
  end
74
145
  end
75
146
 
76
- def self.usage
147
+ def usage
77
148
  "Usage: lesspainful <app> <api_key>"
78
149
  end
79
150
 
80
- def self.verify_arguments
151
+ def verify_arguments
152
+ server = nil
81
153
  log_and_abort(usage) unless app
82
154
  log_and_abort(usage) unless api_key
83
155
  abort_unless(File.exist?(app)) do
156
+ puts usage
84
157
  puts "No such file: #{app}"
85
158
  end
86
159
  abort_unless(/\.(apk|ipa)$/ =~ app) do
87
160
  puts usage
88
161
  puts "<app> should be either an ipa or apk file"
89
162
  end
163
+ if is_ios? and is_macosx? and not ENV['CHECK_IPA'] == '0'
164
+ log_header("Checking ipa for linking with Calabash iOS")
165
+ server = validate_ipa(app)
166
+ abort_unless(server) do
167
+ puts "The .ipa file does not seem to be linked with Calabash."
168
+ puts "Verify that your app is linked correctly."
169
+ puts "To disable this check run with Environment Variable CHECK_IPA=0"
170
+ end
171
+ end
172
+ server
90
173
  end
91
174
 
92
175
  def abort(&block)
@@ -118,7 +201,7 @@ def self.verify_files
118
201
  calabash_gem = Dir.glob("vendor/cache/calabash-android-*").first
119
202
  abort_unless(calabash_gem) do
120
203
  puts "calabash-android was not packaged correct."
121
- puts "Please tell contact@lesspainf.com about this bug"
204
+ puts "Please tell contact@lesspainful.com about this bug."
122
205
  end
123
206
  end
124
207
  end
@@ -128,7 +211,7 @@ end
128
211
 
129
212
  start_at = Time.now
130
213
 
131
- verify_arguments
214
+ server = verify_arguments
132
215
 
133
216
  log_header("Checking for Gemfile")
134
217
  unless File.exist?("Gemfile")
@@ -136,9 +219,19 @@ unless File.exist?("Gemfile")
136
219
  if is_android?
137
220
  log("Creating Gemfile for Android")
138
221
  tgt = File.join(File.dirname(__FILE__),"..","lib","GemfileAndroid")
139
- else
222
+ elsif is_ios?
140
223
  log("Creating Gemfile for iOS")
141
- tgt = File.join(File.dirname(__FILE__),"..","lib","GemfileIOS")
224
+ gemfile = "GemfileIOS"
225
+ if server == :frank
226
+ gemfile = "GemfileIOSFrank"
227
+ end
228
+ tgt = File.join(File.dirname(__FILE__),"..","lib",gemfile)
229
+ else
230
+ abort do
231
+ puts usage
232
+ puts "Your app (second argument) must be an ipa or apk file."
233
+ end
234
+
142
235
  end
143
236
  FileUtils.cp(File.expand_path(tgt), "Gemfile")
144
237
  end
@@ -148,7 +241,11 @@ log_and_abort "Bundler failed. Please check command: bundle package" unless syst
148
241
 
149
242
 
150
243
  log_header("Collecting files")
151
- hashes = all_files.collect { |f| digest(f) }
244
+ collected_files = all_files
245
+ file_paths = collected_files[:files]
246
+ prefix = collected_files[:prefix]
247
+
248
+ hashes = file_paths.collect { |f| digest(f) }
152
249
  hashes << digest(app)
153
250
 
154
251
  log_header("Verifying files")
@@ -166,7 +263,7 @@ cache_status = JSON.parse(response)
166
263
  curl_args = []
167
264
  files = []
168
265
  paths = []
169
- all_files.each do |file|
266
+ file_paths.each do |file|
170
267
  if cache_status[digest(file)]
171
268
  #Server already knows about this file. No need to upload it.
172
269
  files << digest(file)
@@ -174,7 +271,7 @@ all_files.each do |file|
174
271
  #Upload file
175
272
  files << File.new(file)
176
273
  end
177
- paths << file.sub(workspace, "")
274
+ paths << file.sub(prefix, "")
178
275
  end
179
276
 
180
277
  app_file = cache_status[digest(app)] ? digest(app) : File.new(app)
data/lesspainful.gemspec CHANGED
@@ -17,5 +17,6 @@ Gem::Specification.new do |s|
17
17
 
18
18
  s.add_dependency( "bundler","~> 1.2")
19
19
  s.add_dependency( "json")
20
+ s.add_dependency( "rubyzip")
20
21
  s.add_dependency( "rest-client")
21
22
  end
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+ gem "frank-cucumber"
3
+ gem "httpclient"
4
+ gem "slowhandcuke"
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module LessPainful
2
- VERSION = "0.8.0"
2
+ VERSION = "0.9.0"
3
3
  end
data/test/ipa/.irbrc ADDED
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'irb/completion'
3
+ require 'irb/ext/save-history'
4
+
5
+ ARGV.concat [ "--readline",
6
+ "--prompt-mode",
7
+ "simple" ]
8
+
9
+ # 25 entries in the list
10
+ IRB.conf[:SAVE_HISTORY] = 50
11
+
12
+ # Store results in home directory with specified file name
13
+ IRB.conf[:HISTORY_FILE] = ".irb-history"
14
+
15
+ require 'calabash-cucumber/operations'
16
+ include Calabash::Cucumber::Operations
17
+
18
+ def embed(x,y=nil,z=nil)
19
+ puts "Screenshot at #{x}"
20
+ end
Binary file
Binary file
data/test/ipa/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+ gem 'calabash-cucumber'
3
+
@@ -0,0 +1,47 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ CFPropertyList (2.1.1)
5
+ builder (3.1.3)
6
+ calabash-cucumber (0.9.104)
7
+ CFPropertyList
8
+ bundler (~> 1.1)
9
+ cucumber
10
+ httpclient (~> 2.2.7)
11
+ json
12
+ location-one (~> 0.0.6)
13
+ sim_launcher (= 0.3.8)
14
+ slowhandcuke
15
+ cucumber (1.2.1)
16
+ builder (>= 2.1.2)
17
+ diff-lcs (>= 1.1.3)
18
+ gherkin (~> 2.11.0)
19
+ json (>= 1.4.6)
20
+ diff-lcs (1.1.3)
21
+ geocoder (1.1.3)
22
+ gherkin (2.11.2)
23
+ json (>= 1.4.6)
24
+ httpclient (2.2.7)
25
+ json (1.7.5)
26
+ location-one (0.0.6)
27
+ geocoder (~> 1.1)
28
+ httpclient
29
+ json
30
+ rack (1.4.1)
31
+ rack-protection (1.2.0)
32
+ rack
33
+ sim_launcher (0.3.8)
34
+ sinatra
35
+ sinatra (1.3.3)
36
+ rack (~> 1.3, >= 1.3.6)
37
+ rack-protection (~> 1.2)
38
+ tilt (~> 1.3, >= 1.3.3)
39
+ slowhandcuke (0.0.3)
40
+ cucumber
41
+ tilt (1.3.3)
42
+
43
+ PLATFORMS
44
+ ruby
45
+
46
+ DEPENDENCIES
47
+ calabash-cucumber
@@ -0,0 +1,10 @@
1
+ Feature: Running a test
2
+ As an iOS developer
3
+ I want to have a sample feature file
4
+ So I can begin testing quickly
5
+
6
+ Scenario: Example steps
7
+ Given I am on the Welcome Screen
8
+ And take picture
9
+
10
+
@@ -0,0 +1 @@
1
+ require 'calabash-cucumber/calabash_steps'
@@ -0,0 +1,4 @@
1
+ Given /^I am on the Welcome Screen$/ do
2
+ element_exists("view")
3
+ sleep(STEP_PAUSE)
4
+ end
@@ -0,0 +1 @@
1
+ require 'calabash-cucumber/cucumber'
File without changes
@@ -0,0 +1,77 @@
1
+ ########################################
2
+ # #
3
+ # Important Note #
4
+ # #
5
+ # When running calabash-ios tests at #
6
+ # www.lesspainful.com #
7
+ # this file will be overwritten by #
8
+ # a file which automates #
9
+ # app launch on devices. #
10
+ # #
11
+ # Don't rely on this file being #
12
+ # present when running at #
13
+ # www.lesspainful.com. #
14
+ # #
15
+ # Only put stuff here to automate #
16
+ # iOS Simulator. #
17
+ # #
18
+ # You can put your app bundle path #
19
+ # for automating simulator app start: #
20
+ # Uncomment APP_BUNDLE_PATH =.. #
21
+ # #
22
+ ########################################
23
+
24
+ require 'calabash-cucumber/launch/simulator_helper'
25
+ require 'sim_launcher'
26
+
27
+ # Uncomment and replace ?? appropriately
28
+ # This should point to your Simulator build
29
+ # which includes calabash framework
30
+ # this is usually the Calabash build configuration
31
+ # of your production target.
32
+ #APP_BUNDLE_PATH = "~/Library/Developer/Xcode/DerivedData/??/Build/Products/Calabash-iphonesimulator/??.app"
33
+ #
34
+
35
+ def reset_app_jail(sdk, app_path)
36
+ app = File.basename(app_path)
37
+ bundle = `find "#{ENV['HOME']}/Library/Application Support/iPhone Simulator/#{sdk}/Applications/" -type d -depth 2 -name #{app} | head -n 1`
38
+ return if bundle.empty? # Assuming we're already clean
39
+
40
+ sandbox = File.dirname(bundle)
41
+ ['Library', 'Documents', 'tmp'].each do |dir|
42
+ FileUtils.rm_rf(File.join(sandbox, dir))
43
+ end
44
+ end
45
+
46
+ def relaunch
47
+ if ENV['NO_LAUNCH']!="1"
48
+ sdk = ENV['SDK_VERSION'] || SimLauncher::SdkDetector.new().latest_sdk_version
49
+ path = Calabash::Cucumber::SimulatorHelper.app_bundle_or_raise(app_path)
50
+ if ENV['RESET_BETWEEN_SCENARIOS']=="1"
51
+ reset_app_jail(sdk, path)
52
+ end
53
+
54
+ Calabash::Cucumber::SimulatorHelper.relaunch(path,sdk,ENV['DEVICE'] || 'iphone')
55
+ end
56
+ end
57
+
58
+ def app_path
59
+ ENV['APP_BUNDLE_PATH'] || (defined?(APP_BUNDLE_PATH) && APP_BUNDLE_PATH)
60
+ end
61
+
62
+ def calabash_notify
63
+ if self.respond_to?(:on_launch)
64
+ self.on_launch
65
+ end
66
+ end
67
+
68
+ Before do |scenario|
69
+ relaunch
70
+ calabash_notify
71
+ end
72
+
73
+ at_exit do
74
+ if ENV['NO_LAUNCH']!="1" and ENV['NO_STOP']!="1"
75
+ Calabash::Cucumber::SimulatorHelper.stop
76
+ end
77
+ end
Binary file
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ IRBRC=.irbrc OS=ios4 irb
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ IRBRC=.irbrc irb
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lesspainful
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-20 00:00:00.000000000 Z
12
+ date: 2012-09-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -43,6 +43,22 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rubyzip
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
46
62
  - !ruby/object:Gem::Dependency
47
63
  name: rest-client
48
64
  requirement: !ruby/object:Gem::Requirement
@@ -68,6 +84,7 @@ executables:
68
84
  extensions: []
69
85
  extra_rdoc_files: []
70
86
  files:
87
+ - .gitignore
71
88
  - Gemfile
72
89
  - Gemfile.lock
73
90
  - Rakefile
@@ -75,7 +92,22 @@ files:
75
92
  - lesspainful.gemspec
76
93
  - lib/GemfileAndroid
77
94
  - lib/GemfileIOS
95
+ - lib/GemfileIOSFrank
78
96
  - lib/version.rb
97
+ - test/ipa/.irbrc
98
+ - test/ipa/2012 Olympics_cal.ipa
99
+ - test/ipa/2012 Olympics_no_cal.ipa
100
+ - test/ipa/Gemfile
101
+ - test/ipa/Gemfile.lock
102
+ - test/ipa/features.zip
103
+ - test/ipa/features/my_first.feature
104
+ - test/ipa/features/step_definitions/calabash_steps.rb
105
+ - test/ipa/features/step_definitions/my_first_steps.rb
106
+ - test/ipa/features/support/env.rb
107
+ - test/ipa/features/support/hooks.rb
108
+ - test/ipa/features/support/launch.rb
109
+ - test/ipa/irb_ios4.sh
110
+ - test/ipa/irb_ios5.sh
79
111
  homepage: http://www.lesspainful.com
80
112
  licenses: []
81
113
  post_install_message:
@@ -96,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
128
  version: '0'
97
129
  requirements: []
98
130
  rubyforge_project:
99
- rubygems_version: 1.8.24
131
+ rubygems_version: 1.8.23
100
132
  signing_key:
101
133
  specification_version: 3
102
134
  summary: Client for uploading calabash test to www.lesspainful.com