lesspainful 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile.lock +3 -1
- data/bin/lesspainful +110 -13
- data/lesspainful.gemspec +1 -0
- data/lib/GemfileIOSFrank +4 -0
- data/lib/version.rb +1 -1
- data/test/ipa/.irbrc +20 -0
- data/test/ipa/2012 Olympics_cal.ipa +0 -0
- data/test/ipa/2012 Olympics_no_cal.ipa +0 -0
- data/test/ipa/Gemfile +3 -0
- data/test/ipa/Gemfile.lock +47 -0
- data/test/ipa/features/my_first.feature +10 -0
- data/test/ipa/features/step_definitions/calabash_steps.rb +1 -0
- data/test/ipa/features/step_definitions/my_first_steps.rb +4 -0
- data/test/ipa/features/support/env.rb +1 -0
- data/test/ipa/features/support/hooks.rb +0 -0
- data/test/ipa/features/support/launch.rb +77 -0
- data/test/ipa/features.zip +0 -0
- data/test/ipa/irb_ios4.sh +2 -0
- data/test/ipa/irb_ios5.sh +2 -0
- metadata +35 -3
data/.gitignore
ADDED
data/Gemfile.lock
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
lesspainful (0.0
|
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
|
-
|
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
|
-
"#{
|
71
|
+
File.join(workspace,"test_servers","#{digest}_#{calabash_android_version}.apk")
|
43
72
|
end
|
44
73
|
|
45
74
|
def all_files
|
46
|
-
|
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
|
147
|
+
def usage
|
77
148
|
"Usage: lesspainful <app> <api_key>"
|
78
149
|
end
|
79
150
|
|
80
|
-
def
|
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@
|
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
|
-
|
222
|
+
elsif is_ios?
|
140
223
|
log("Creating Gemfile for iOS")
|
141
|
-
|
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
|
-
|
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
|
-
|
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(
|
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
data/lib/GemfileIOSFrank
ADDED
data/lib/version.rb
CHANGED
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,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 @@
|
|
1
|
+
require 'calabash-cucumber/calabash_steps'
|
@@ -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
|
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.
|
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-
|
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.
|
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
|