calabash-cucumber 0.9.68 → 0.9.70

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.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- calabash-cucumber (0.9.68)
4
+ calabash-cucumber (0.9.70)
5
5
  CFPropertyList
6
6
  cucumber
7
7
  json
@@ -20,9 +20,9 @@ GEM
20
20
  gherkin (~> 2.11.0)
21
21
  json (>= 1.4.6)
22
22
  diff-lcs (1.1.3)
23
- gherkin (2.11.0)
23
+ gherkin (2.11.1)
24
24
  json (>= 1.4.6)
25
- json (1.6.4)
25
+ json (1.7.3)
26
26
  net-http-persistent (2.7)
27
27
  rack (1.4.1)
28
28
  rack-protection (1.2.0)
Binary file
@@ -103,11 +103,14 @@ def calabash_submit(args)
103
103
  end
104
104
  system ("zip -r -o #{archive_path} #{feature_path}")
105
105
 
106
+
107
+
108
+ url = ENV['SUBMIT_URL'] || "https://www.lesspainful.com/cmd_upload"
109
+
106
110
  msg("Info") do
107
- puts "Uploading ipa and features to www.lesspainful.com"
111
+ puts "Uploading ipa and features to #{url}"
108
112
  end
109
-
110
- result = `curl -F "secret=#{secret}" -F "app=@#{ipa_file}" -F "env=@#{archive_path}" https://www.lesspainful.com/cmd_upload`
113
+ result = `curl -F "secret=#{secret}" -F "app=@#{ipa_file}" -F "env=@#{archive_path}" #{url}`
111
114
 
112
115
  if is_json? result
113
116
  json_result = JSON.parse(result)
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Karl Krukow"]
10
10
  s.email = ["karl@lesspainful.com"]
11
- s.homepage = "http://www.lesspainful.com/calabash"
11
+ s.homepage = "http://calaba.sh"
12
12
  s.summary = %q{Client for calabash-ios-server for automated functional testing on iOS}
13
13
  s.description = %q{calabash-cucumber drives tests for native iOS apps. You must link your app with calabash-ios-server framework to execute tests.}
14
14
  s.files = `git ls-files`.split("\n")
@@ -4,5 +4,9 @@ Feature: Running a test
4
4
  So I can begin testing quickly
5
5
 
6
6
  Scenario: Example steps
7
- Given the app is running
8
- Then take picture
7
+ Given I am on the Welcome Screen
8
+ When I swipe left
9
+ Then I wait until I don't see "Please swipe left"
10
+ And take picture
11
+
12
+
@@ -0,0 +1,4 @@
1
+ Given /^I am on the Welcome Screen$/ do
2
+ element_exists("view")
3
+ sleep(STEP_PAUSE)
4
+ end
@@ -10,6 +10,8 @@ module Calabash
10
10
  DERIVED_DATA = File.expand_path("~/Library/Developer/Xcode/DerivedData")
11
11
  DEFAULT_DERIVED_DATA_INFO = File.expand_path("#{DERIVED_DATA}/*/info.plist")
12
12
 
13
+ DEFAULT_SIM_WAIT = "15"
14
+
13
15
  MAX_PING_ATTEMPTS = 5
14
16
 
15
17
  def self.relaunch(path, sdk = nil, version = 'iphone')
@@ -161,7 +163,8 @@ module Calabash
161
163
 
162
164
  def self.ensure_connectivity(app_bundle_path, sdk, version)
163
165
  begin
164
- Timeout::timeout(15) do
166
+ timeout = (ENV['CONNECT_TIMEOUT'] || DEFAULT_SIM_WAIT).to_i
167
+ Timeout::timeout(timeout) do
165
168
  connected = false
166
169
  until connected
167
170
  simulator = launch(app_bundle_path, sdk, version)
@@ -7,437 +7,481 @@ if not Object.const_defined?(:CALABASH_COUNT)
7
7
  end
8
8
 
9
9
 
10
+ module Calabash
11
+ module Cucumber
10
12
 
13
+ module Operations
11
14
 
12
- module Calabash module Cucumber
15
+ DATA_PATH = File.expand_path(File.dirname(__FILE__))
13
16
 
14
- module Operations
17
+ KEYBOARD_SMALL_LETTERS = "Keyboard_Small-Letters"
18
+ KEYBOARD_CAPITAL_LETTERS = "Keyboard_Capital-Letters"
19
+ KEYBOARD_NUMBERS_AND_PUNCTUATION = "Keyboard_Numbers-And-Punctuation"
15
20
 
16
- DATA_PATH = File.expand_path(File.dirname(__FILE__))
17
-
18
- def macro(txt)
19
- if self.respond_to?:step
20
- step(txt)
21
- else
22
- Then txt
23
- end
24
- end
21
+ def macro(txt)
22
+ if self.respond_to? :step
23
+ step(txt)
24
+ else
25
+ Then txt
26
+ end
27
+ end
25
28
 
26
- def home_direction
27
- @current_rotation = @current_rotation || :down
28
- end
29
+ def home_direction
30
+ @current_rotation = @current_rotation || :down
31
+ end
29
32
 
30
- def assert_home_direction(expected)
31
- unless expected.to_sym == home_direction
32
- screenshot_and_raise "Expected home button to have direction #{expected} but had #{home_direction}"
33
- end
34
- end
33
+ def assert_home_direction(expected)
34
+ unless expected.to_sym == home_direction
35
+ screenshot_and_raise "Expected home button to have direction #{expected} but had #{home_direction}"
36
+ end
37
+ end
35
38
 
36
- def escape_quotes(str)
37
- str.gsub("'","\\\\'")
38
- end
39
+ def escape_quotes(str)
40
+ str.gsub("'", "\\\\'")
41
+ end
39
42
 
40
- def wait_for(timeout, &block)
41
- begin
42
- Timeout::timeout(timeout) do
43
- until block.call
44
- sleep 0.3
43
+ def wait_for(timeout, &block)
44
+ begin
45
+ Timeout::timeout(timeout) do
46
+ until block.call
47
+ sleep 0.3
48
+ end
49
+ end
50
+ rescue Exception => e
51
+ screenshot_and_raise e
45
52
  end
46
53
  end
47
- rescue Exception => e
48
- screenshot_and_raise e
49
- end
50
- end
51
54
 
52
- def wait_ready(timeout, times=2,sleep=0.3, &block)
53
- raise "Times parameter must be greater than or equal 2" if times < 2
54
- raise "Sleep parameter must be greater than 0" if sleep <= 0
55
- begin
56
- Timeout::timeout(timeout) do
57
- while times > 0 do
58
- if block.call
59
- times -= 1
55
+ def wait_ready(timeout, times=2, sleep=0.3, &block)
56
+ raise "Times parameter must be greater than or equal 2" if times < 2
57
+ raise "Sleep parameter must be greater than 0" if sleep <= 0
58
+ begin
59
+ Timeout::timeout(timeout) do
60
+ while times > 0 do
61
+ if block.call
62
+ times -= 1
63
+ end
64
+ sleep 0.3
65
+ end
60
66
  end
61
- sleep 0.3
67
+ rescue Exception => e
68
+ screenshot_and_raise e
62
69
  end
63
70
  end
64
- rescue Exception => e
65
- screenshot_and_raise e
66
- end
67
- end
68
71
 
69
- def query(uiquery, *args)
70
- map(uiquery, :query, *args)
71
- end
72
+ def query(uiquery, *args)
73
+ map(uiquery, :query, *args)
74
+ end
72
75
 
73
- def label(uiquery)
74
- query(uiquery, :accessibilityLabel)
75
- end
76
+ def label(uiquery)
77
+ query(uiquery, :accessibilityLabel)
78
+ end
76
79
 
77
- def screenshot_and_raise(msg)
78
- screenshot
79
- sleep 5
80
- raise(msg)
81
- end
80
+ def screenshot_and_raise(msg)
81
+ screenshot
82
+ sleep 5
83
+ raise(msg)
84
+ end
82
85
 
83
- def touch(uiquery,options={})
84
- options[:query] = uiquery
85
- views_touched = playback("touch",options)
86
- unless uiquery.nil?
87
- screenshot_and_raise "could not find view to touch: '#{uiquery}', args: #{options}" if views_touched.empty?
88
- end
89
- views_touched
90
- end
86
+ def touch(uiquery, options={})
87
+ options[:query] = uiquery
88
+ views_touched = playback("touch", options)
89
+ unless uiquery.nil?
90
+ screenshot_and_raise "could not find view to touch: '#{uiquery}', args: #{options}" if views_touched.empty?
91
+ end
92
+ views_touched
93
+ end
91
94
 
92
- def simple_touch(label,*args)
93
- touch("view marked:'#{label}'", *args)
94
- end
95
+ def simple_touch(label, *args)
96
+ touch("view marked:'#{label}'", *args)
97
+ end
95
98
 
96
- def tap(label,*args)
97
- simple_touch(label,*args)
98
- end
99
+ def tap(label, *args)
100
+ simple_touch(label, *args)
101
+ end
99
102
 
100
- def html(q)
101
- query(q).map {|e| e['html']}
102
- end
103
+ def html(q)
104
+ query(q).map { |e| e['html'] }
105
+ end
103
106
 
104
- def ok
105
- touch("view marked:'ok'")
106
- end
107
+ def ok
108
+ touch("view marked:'ok'")
109
+ end
107
110
 
108
- def set_text(uiquery, txt)
109
- text_fields_modified = map(uiquery, :setText, txt)
110
- screenshot_and_raise "could not find text field #{uiquery}" if text_fields_modified.empty?
111
- text_fields_modified
112
- end
111
+ def set_text(uiquery, txt)
112
+ text_fields_modified = map(uiquery, :setText, txt)
113
+ screenshot_and_raise "could not find text field #{uiquery}" if text_fields_modified.empty?
114
+ text_fields_modified
115
+ end
113
116
 
114
117
 
115
- def swipe(dir,options={})
116
- dir = dir.to_sym
117
- @current_rotation = @current_rotation || :down
118
- if @current_rotation == :left
118
+ def swipe(dir, options={})
119
+ dir = dir.to_sym
120
+ @current_rotation = @current_rotation || :down
121
+ if @current_rotation == :left
119
122
  case dir
120
- when :left then dir = :down
121
- when :right then dir = :up
122
- when :up then dir = :left
123
- when :down then dir = :right
124
- else
123
+ when :left then
124
+ dir = :down
125
+ when :right then
126
+ dir = :up
127
+ when :up then
128
+ dir = :left
129
+ when :down then
130
+ dir = :right
131
+ else
125
132
  end
126
- end
127
- if @current_rotation == :right
133
+ end
134
+ if @current_rotation == :right
128
135
  case dir
129
- when :left then dir = :up
130
- when :right then dir = :down
131
- when :up then dir = :right
132
- when :down then dir = :left
133
- else
136
+ when :left then
137
+ dir = :up
138
+ when :right then
139
+ dir = :down
140
+ when :up then
141
+ dir = :right
142
+ when :down then
143
+ dir = :left
144
+ else
134
145
  end
135
- end
136
- if @current_rotation == :up
146
+ end
147
+ if @current_rotation == :up
137
148
  case dir
138
- when :left then dir = :right
139
- when :right then dir = :left
140
- when :up then dir = :down
141
- when :down then dir = :up
142
- else
149
+ when :left then
150
+ dir = :right
151
+ when :right then
152
+ dir = :left
153
+ when :up then
154
+ dir = :down
155
+ when :down then
156
+ dir = :up
157
+ else
143
158
  end
159
+ end
160
+ playback("swipe_#{dir}", options)
144
161
  end
145
- playback("swipe_#{dir}",options)
146
- end
147
162
 
148
- def cell_swipe(options={})
149
- playback("cell_swipe",options)
150
- end
163
+ def cell_swipe(options={})
164
+ playback("cell_swipe", options)
165
+ end
151
166
 
152
- def done
153
- map(nil,:touchDone,load_playback_data("touch_done"))
154
- end
167
+ def done
168
+ map(nil, :keyboard, load_playback_data("touch_done"))
169
+ end
155
170
 
156
- #Possible values
157
- # 'Dictation'
158
- # 'Shift'
159
- # 'Delete'
160
- # 'International'
161
- # 'More'
171
+ #Possible values
172
+ # 'Dictation'
173
+ # 'Shift'
174
+ # 'Delete'
175
+ # 'International'
176
+ # 'More'
177
+ def keyboard_enter_char(chr)
178
+ map(nil, :keyboard, load_playback_data("touch_done"), chr)
179
+ end
162
180
 
163
- def keyboard_enter_char(chr)
164
- map(nil,:touchDone,load_playback_data("touch_done"),chr)
165
- end
181
+ def keyboard_change_keyplane(plane)
182
+ desc = query("view:'UIKBKeyplaneView'", "keyplane", "description")
183
+ return nil if desc.empty?
184
+ desc = desc.first
185
+ plane_exp = Regexp.new(plane)
186
+ if not plane_exp.match(desc)
187
+ keyboard_enter_char "Shift"
188
+ sleep(0.3)
189
+ desc = query("view:'UIKBKeyplaneView'", "keyplane", "description").first
190
+ if not plane_exp.match(desc)
191
+ keyboard_enter_char "Shift"
192
+ sleep(0.3)
193
+ return nil
194
+ end
195
+ end
196
+ desc
197
+ end
166
198
 
167
- def scroll(uiquery,direction)
168
- views_touched=map(uiquery, :scroll, direction)
169
- screenshot_and_raise "could not find view to scroll: '#{uiquery}', args: #{direction}" if views_touched.empty?
170
- views_touched
171
- end
199
+ #TODO only letters now
200
+ def keyboard_enter_text(text)
201
+ text.each_char do |ch|
202
+ if /[a-z]/.match(ch)
203
+ keyboard_change_keyplane(KEYBOARD_SMALL_LETTERS)
204
+ elsif /\d/.match(ch)
205
+ #Todo - handle digits and special chars
206
+ raise "Digits and special chars not handled by keyboard_enter_text yet."
207
+ else
208
+ keyboard_change_keyplane(KEYBOARD_CAPITAL_LETTERS)
209
+ end
210
+ keyboard_enter_char(ch)
211
+ sleep(0.3)
212
+ end
213
+ end
172
214
 
173
- def scroll_to_row(uiquery,number)
174
- views_touched=map(uiquery, :scrollToRow, number)
175
- if views_touched.empty? or views_touched.member?"<VOID>"
176
- screenshot_and_raise "Unable to scroll: '#{uiquery}' to: #{number}"
177
- end
178
- views_touched
179
- end
180
215
 
181
- def pinch(in_out,options={})
182
- file = "pinch_in"
183
- if in_out.to_sym==:out
184
- file = "pinch_out"
185
- end
186
- playback(file, options)
187
- end
216
+ def scroll(uiquery, direction)
217
+ views_touched=map(uiquery, :scroll, direction)
218
+ screenshot_and_raise "could not find view to scroll: '#{uiquery}', args: #{direction}" if views_touched.empty?
219
+ views_touched
220
+ end
188
221
 
189
- def rotate(dir)
190
- @current_rotation = @current_rotation || :down
191
- rotate_cmd = nil
192
- case dir
193
- when :left then
194
- if @current_rotation == :down
195
- rotate_cmd = "left_home_down"
196
- @current_rotation = :right
197
- elsif @current_rotation == :right
198
- rotate_cmd = "left_home_right"
199
- @current_rotation = :up
200
- elsif @current_rotation == :left
201
- rotate_cmd = "left_home_left"
202
- @current_rotation = :down
203
- elsif @current_rotation == :up
204
- rotate_cmd = "left_home_up"
205
- @current_rotation = :left
222
+ def scroll_to_row(uiquery, number)
223
+ views_touched=map(uiquery, :scrollToRow, number)
224
+ if views_touched.empty? or views_touched.member? "<VOID>"
225
+ screenshot_and_raise "Unable to scroll: '#{uiquery}' to: #{number}"
206
226
  end
207
- when :right then
208
- if @current_rotation == :down
209
- rotate_cmd = "right_home_down"
210
- @current_rotation = :left
211
- elsif @current_rotation == :left
212
- rotate_cmd = "right_home_left"
213
- @current_rotation = :up
214
- elsif @current_rotation == :right
215
- rotate_cmd = "right_home_right"
216
- @current_rotation = :down
217
- elsif @current_rotation == :up
218
- rotate_cmd = "right_home_up"
219
- @current_rotation = :right
227
+ views_touched
228
+ end
229
+
230
+ def pinch(in_out, options={})
231
+ file = "pinch_in"
232
+ if in_out.to_sym==:out
233
+ file = "pinch_out"
220
234
  end
221
- end
235
+ playback(file, options)
236
+ end
222
237
 
223
- if rotate_cmd.nil?
224
- screenshot_and_raise "Does not support rotating #{dir} when home button is pointing #{@current_rotation}"
225
- end
226
- playback("rotate_#{rotate_cmd}")
227
- end
238
+ def rotate(dir)
239
+ @current_rotation = @current_rotation || :down
240
+ rotate_cmd = nil
241
+ case dir
242
+ when :left then
243
+ if @current_rotation == :down
244
+ rotate_cmd = "left_home_down"
245
+ @current_rotation = :right
246
+ elsif @current_rotation == :right
247
+ rotate_cmd = "left_home_right"
248
+ @current_rotation = :up
249
+ elsif @current_rotation == :left
250
+ rotate_cmd = "left_home_left"
251
+ @current_rotation = :down
252
+ elsif @current_rotation == :up
253
+ rotate_cmd = "left_home_up"
254
+ @current_rotation = :left
255
+ end
256
+ when :right then
257
+ if @current_rotation == :down
258
+ rotate_cmd = "right_home_down"
259
+ @current_rotation = :left
260
+ elsif @current_rotation == :left
261
+ rotate_cmd = "right_home_left"
262
+ @current_rotation = :up
263
+ elsif @current_rotation == :right
264
+ rotate_cmd = "right_home_right"
265
+ @current_rotation = :down
266
+ elsif @current_rotation == :up
267
+ rotate_cmd = "right_home_up"
268
+ @current_rotation = :right
269
+ end
270
+ end
228
271
 
229
- def background(secs)
230
- res = http({:method=>:post, :path=>'background'}, {:duration => secs})
231
- end
272
+ if rotate_cmd.nil?
273
+ screenshot_and_raise "Does not support rotating #{dir} when home button is pointing #{@current_rotation}"
274
+ end
275
+ playback("rotate_#{rotate_cmd}")
276
+ end
232
277
 
233
- def element_exists(uiquery)
234
- !query(uiquery).empty?
235
- end
278
+ def background(secs)
279
+ res = http({:method=>:post, :path=>'background'}, {:duration => secs})
280
+ end
236
281
 
237
- def view_with_mark_exists(expected_mark)
238
- element_exists( "view marked:'#{expected_mark}'" )
239
- end
282
+ def element_exists(uiquery)
283
+ !query(uiquery).empty?
284
+ end
240
285
 
241
- def check_element_exists( query )
242
- if not element_exists( query )
243
- screenshot_and_raise "No element found for query: #{query}"
244
- end
245
- end
286
+ def view_with_mark_exists(expected_mark)
287
+ element_exists("view marked:'#{expected_mark}'")
288
+ end
246
289
 
247
- def check_element_does_not_exist( query )
248
- if element_exists( query )
249
- screenshot_and_raise "Expected no elements to match query: #{query}"
250
- end
251
- end
290
+ def check_element_exists(query)
291
+ if not element_exists(query)
292
+ screenshot_and_raise "No element found for query: #{query}"
293
+ end
294
+ end
252
295
 
253
- def check_view_with_mark_exists(expected_mark)
254
- check_element_exists( "view marked:'#{expected_mark}'" )
255
- end
296
+ def check_element_does_not_exist(query)
297
+ if element_exists(query)
298
+ screenshot_and_raise "Expected no elements to match query: #{query}"
299
+ end
300
+ end
256
301
 
257
- # a better name would be element_exists_and_is_not_hidden
258
- def element_is_not_hidden(uiquery)
259
- matches = query(uiquery, 'isHidden')
260
- matches.delete(true)
261
- !matches.empty?
262
- end
302
+ def check_view_with_mark_exists(expected_mark)
303
+ check_element_exists("view marked:'#{expected_mark}'")
304
+ end
263
305
 
306
+ # a better name would be element_exists_and_is_not_hidden
307
+ def element_is_not_hidden(uiquery)
308
+ matches = query(uiquery, 'isHidden')
309
+ matches.delete(true)
310
+ !matches.empty?
311
+ end
264
312
 
265
- def load_playback_data(recording,options={})
266
- os = options["OS"] || ENV["OS"] || "ios5"
267
- device = options["DEVICE"] || ENV["DEVICE"] || "iphone"
268
313
 
269
- rec_dir = ENV['PLAYBACK_DIR'] || "#{Dir.pwd}/playback"
270
- if !recording.end_with?".base64"
271
- recording = "#{recording}_#{os}_#{device}.base64"
272
- end
273
- data = nil
274
- if (File.exists?(recording))
275
- data = File.read(recording)
276
- elsif (File.exists?("features/#{recording}"))
277
- data = File.read("features/#{recording}")
278
- elsif (File.exists?("#{rec_dir}/#{recording}"))
279
- data = File.read("#{rec_dir}/#{recording}")
280
- elsif (File.exists?("#{DATA_PATH}/resources/#{recording}"))
281
- data = File.read("#{DATA_PATH}/resources/#{recording}")
282
- else
283
- screenshot_and_raise "Playback not found: #{recording} (searched for #{recording} in #{Dir.pwd}, #{rec_dir}, #{DATA_PATH}/resources"
284
- end
285
- data
286
- end
287
- def playback(recording, options={})
288
- data = load_playback_data(recording)
314
+ def load_playback_data(recording, options={})
315
+ os = options["OS"] || ENV["OS"] || "ios5"
316
+ device = options["DEVICE"] || ENV["DEVICE"] || "iphone"
289
317
 
290
- post_data = %Q|{"events":"#{data}"|
291
- post_data<< %Q|,"query":"#{escape_quotes(options[:query])}"| if options[:query]
292
- post_data<< %Q|,"offset":#{options[:offset].to_json}| if options[:offset]
293
- post_data<< %Q|,"reverse":#{options[:reverse]}| if options[:reverse]
294
- post_data<< %Q|,"prototype":"#{options[:prototype]}"| if options[:prototype]
295
- post_data << "}"
318
+ rec_dir = ENV['PLAYBACK_DIR'] || "#{Dir.pwd}/playback"
319
+ if !recording.end_with? ".base64"
320
+ recording = "#{recording}_#{os}_#{device}.base64"
321
+ end
322
+ data = nil
323
+ if (File.exists?(recording))
324
+ data = File.read(recording)
325
+ elsif (File.exists?("features/#{recording}"))
326
+ data = File.read("features/#{recording}")
327
+ elsif (File.exists?("#{rec_dir}/#{recording}"))
328
+ data = File.read("#{rec_dir}/#{recording}")
329
+ elsif (File.exists?("#{DATA_PATH}/resources/#{recording}"))
330
+ data = File.read("#{DATA_PATH}/resources/#{recording}")
331
+ else
332
+ screenshot_and_raise "Playback not found: #{recording} (searched for #{recording} in #{Dir.pwd}, #{rec_dir}, #{DATA_PATH}/resources"
333
+ end
334
+ data
335
+ end
296
336
 
297
- res = http({:method=>:post, :raw=>true, :path=>'play'}, post_data)
337
+ def playback(recording, options={})
338
+ data = load_playback_data(recording)
298
339
 
299
- res = JSON.parse( res )
300
- if res['outcome'] != 'SUCCESS'
301
- screenshot_and_raise "playback failed because: #{res['reason']}\n#{res['details']}"
302
- end
303
- res['results']
304
- end
340
+ post_data = %Q|{"events":"#{data}"|
341
+ post_data<< %Q|,"query":"#{escape_quotes(options[:query])}"| if options[:query]
342
+ post_data<< %Q|,"offset":#{options[:offset].to_json}| if options[:offset]
343
+ post_data<< %Q|,"reverse":#{options[:reverse]}| if options[:reverse]
344
+ post_data<< %Q|,"prototype":"#{options[:prototype]}"| if options[:prototype]
345
+ post_data << "}"
346
+
347
+ res = http({:method=>:post, :raw=>true, :path=>'play'}, post_data)
348
+
349
+ res = JSON.parse(res)
350
+ if res['outcome'] != 'SUCCESS'
351
+ screenshot_and_raise "playback failed because: #{res['reason']}\n#{res['details']}"
352
+ end
353
+ res['results']
354
+ end
305
355
 
306
- def interpolate(recording, options={})
307
- data = load_playback_data(recording)
356
+ def interpolate(recording, options={})
357
+ data = load_playback_data(recording)
308
358
 
309
- post_data = %Q|{"events":"#{data}"|
310
- post_data<< %Q|,"start":"#{escape_quotes(options[:start])}"| if options[:start]
311
- post_data<< %Q|,"end":"#{escape_quotes(options[:end])}"| if options[:end]
312
- post_data<< %Q|,"offset_start":#{options[:offset_start].to_json}| if options[:offset_start]
313
- post_data<< %Q|,"offset_end":#{options[:offset_end].to_json}| if options[:offset_end]
314
- post_data << "}"
359
+ post_data = %Q|{"events":"#{data}"|
360
+ post_data<< %Q|,"start":"#{escape_quotes(options[:start])}"| if options[:start]
361
+ post_data<< %Q|,"end":"#{escape_quotes(options[:end])}"| if options[:end]
362
+ post_data<< %Q|,"offset_start":#{options[:offset_start].to_json}| if options[:offset_start]
363
+ post_data<< %Q|,"offset_end":#{options[:offset_end].to_json}| if options[:offset_end]
364
+ post_data << "}"
315
365
 
316
- res = http({:method=>:post, :raw=>true, :path=>'interpolate'}, post_data)
366
+ res = http({:method=>:post, :raw=>true, :path=>'interpolate'}, post_data)
317
367
 
318
- res = JSON.parse( res )
319
- if res['outcome'] != 'SUCCESS'
320
- screenshot_and_raise "interpolate failed because: #{res['reason']}\n#{res['details']}"
368
+ res = JSON.parse(res)
369
+ if res['outcome'] != 'SUCCESS'
370
+ screenshot_and_raise "interpolate failed because: #{res['reason']}\n#{res['details']}"
371
+ end
372
+ res['results']
321
373
  end
322
- res['results']
323
- end
324
374
 
325
- def record_begin
326
- http({:method=>:post, :path=>'record'}, {:action => :start})
327
- end
375
+ def record_begin
376
+ http({:method=>:post, :path=>'record'}, {:action => :start})
377
+ end
328
378
 
329
- def record_end(file_name)
330
- res = http({:method=>:post, :path=>'record'}, {:action => :stop})
331
- File.open("_recording.plist",'wb') do |f|
332
- f.write res
333
- end
334
- device = ENV['DEVICE'] || 'iphone'
335
- os = ENV['OS']
336
- if not os and ENV['SDK_VERSION']
337
- sdk = ENV['SDK_VERSION']
338
- if sdk[0] != '4' and sdk[0] != '5'
339
- raise "SDK_VERSION should be 4.x or 5.x"
340
- end
341
- os = "ios#{sdk[0]}"
342
- elsif os.nil? and ENV['SDK_VERSION'].nil?
343
- raise "Either SDK_VERSION or OS environment vars must be set."
344
- end
345
- file_name = "#{file_name}_#{os}_#{device}.base64"
346
- system("/usr/bin/plutil -convert binary1 -o _recording_binary.plist _recording.plist")
347
- system("openssl base64 -in _recording_binary.plist -out #{file_name}")
348
- system("rm _recording.plist _recording_binary.plist")
349
- file_name
350
- end
379
+ def record_end(file_name)
380
+ res = http({:method=>:post, :path=>'record'}, {:action => :stop})
381
+ File.open("_recording.plist", 'wb') do |f|
382
+ f.write res
383
+ end
384
+ device = ENV['DEVICE'] || 'iphone'
385
+ os = ENV['OS'] || 'ios5'
386
+
387
+ file_name = "#{file_name}_#{os}_#{device}.base64"
388
+ system("/usr/bin/plutil -convert binary1 -o _recording_binary.plist _recording.plist")
389
+ system("openssl base64 -in _recording_binary.plist -out #{file_name}")
390
+ system("rm _recording.plist _recording_binary.plist")
391
+ file_name
392
+ end
351
393
 
352
- def backdoor(sel, arg)
353
- json = {
354
- :selector => sel,
355
- :arg => arg
356
- }
357
- res = http({:method=>:post, :path=>'backdoor'}, json)
358
- res = JSON.parse(res)
359
- if res['outcome'] != 'SUCCESS'
360
- screenshot_and_raise "map #{query}, #{method_name} failed because: #{res['reason']}\n#{res['details']}"
361
- end
362
- res['result']
363
- end
394
+ def backdoor(sel, arg)
395
+ json = {
396
+ :selector => sel,
397
+ :arg => arg
398
+ }
399
+ res = http({:method=>:post, :path=>'backdoor'}, json)
400
+ res = JSON.parse(res)
401
+ if res['outcome'] != 'SUCCESS'
402
+ screenshot_and_raise "backdoor #{json} failed because: #{res['reason']}\n#{res['details']}"
403
+ end
404
+ res['result']
405
+ end
364
406
 
365
- #def screencast_begin
366
- # http({:method=>:post, :path=>'screencast'}, {:action => :start})
367
- #end
368
- #
369
- #def screencast_end(file_name)
370
- # res = http({:method=>:post, :path=>'screencast'}, {:action => :stop})
371
- # File.open(file_name,'wb') do |f|
372
- # f.write res
373
- # end
374
- # file_name
375
- #end
376
-
377
- def screenshot
378
- res = http({:method =>:get, :path => 'screenshot'})
379
- prefix = ENV['SCREENSHOT_PATH'] || ""
380
- path = "#{prefix}screenshot_#{CALABASH_COUNT[:step_line]}.png"
381
- File.open(path,'wb') do |f|
382
- f.write res
383
- end
384
- puts "Saved screenshot: #{path}"
385
- path
386
- end
407
+ #def screencast_begin
408
+ # http({:method=>:post, :path=>'screencast'}, {:action => :start})
409
+ #end
410
+ #
411
+ #def screencast_end(file_name)
412
+ # res = http({:method=>:post, :path=>'screencast'}, {:action => :stop})
413
+ # File.open(file_name,'wb') do |f|
414
+ # f.write res
415
+ # end
416
+ # file_name
417
+ #end
418
+
419
+ def screenshot(prefix=nil, name=nil)
420
+ res = http({:method =>:get, :path => 'screenshot'})
421
+ prefix = prefix || ENV['SCREENSHOT_PATH'] || ""
422
+ name = "screenshot_#{CALABASH_COUNT[:step_line]}.png" if name.nil?
423
+ path = "#{prefix}#{name}"
424
+ File.open(path, 'wb') do |f|
425
+ f.write res
426
+ end
427
+ puts "Saved screenshot: #{path}"
428
+ path
429
+ end
387
430
 
388
- def map( query, method_name, *method_args )
389
- operation_map = {
390
- :method_name => method_name,
391
- :arguments => method_args
392
- }
393
- res = http({:method=>:post, :path=>'map'},
394
- {:query => query, :operation => operation_map})
395
- res = JSON.parse(res)
396
- if res['outcome'] != 'SUCCESS'
397
- screenshot_and_raise "map #{query}, #{method_name} failed because: #{res['reason']}\n#{res['details']}"
398
- end
431
+ def map(query, method_name, *method_args)
432
+ operation_map = {
433
+ :method_name => method_name,
434
+ :arguments => method_args
435
+ }
436
+ res = http({:method=>:post, :path=>'map'},
437
+ {:query => query, :operation => operation_map})
438
+ res = JSON.parse(res)
439
+ if res['outcome'] != 'SUCCESS'
440
+ screenshot_and_raise "map #{query}, #{method_name} failed because: #{res['reason']}\n#{res['details']}"
441
+ end
399
442
 
400
- res['results']
401
- end
443
+ res['results']
444
+ end
402
445
 
403
- def http(options, data=nil)
404
- url = url_for(options[:path])
405
- if options[:method] == :post
406
- req = Net::HTTP::Post.new url.path
407
- if options[:raw]
408
- req.body=data
409
- else
410
- req.body = data.to_json
446
+ def http(options, data=nil)
447
+ url = url_for(options[:path])
448
+ if options[:method] == :post
449
+ req = Net::HTTP::Post.new url.path
450
+ if options[:raw]
451
+ req.body=data
452
+ else
453
+ req.body = data.to_json
454
+ end
455
+
456
+ else
457
+ req = Net::HTTP::Get.new url.path
458
+ end
459
+ make_http_request(url, req)
411
460
  end
412
461
 
413
- else
414
- req = Net::HTTP::Get.new url.path
415
- end
416
- make_http_request( url, req )
417
- end
418
462
 
463
+ def url_for(verb)
464
+ url = URI.parse(ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/")
465
+ url.path = '/'+verb
466
+ url
467
+ end
419
468
 
420
- def url_for( verb )
421
- url = URI.parse(ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/")
422
- url.path = '/'+verb
423
- url
424
- end
469
+ def make_http_request(url, req)
470
+ @http = Net::HTTP.new(url.host, url.port)
471
+ res = @http.start do |sess|
472
+ sess.request req
473
+ end
474
+ body = res.body
475
+ begin
476
+ @http.finish if @http and @http.started?
477
+ rescue Exception => e
478
+ puts "Finish #{e}"
479
+ end
480
+ body
481
+ end
425
482
 
426
- def make_http_request( url, req )
427
- @http = Net::HTTP.new(url.host, url.port)
428
- res = @http.start do |sess|
429
- sess.request req
430
483
  end
431
- body = res.body
432
- begin
433
- @http.finish if @http and @http.started?
434
- rescue Exception => e
435
- puts "Finish #{e}"
436
- end
437
- body
438
- end
439
-
440
- end
441
484
 
442
485
 
443
- end end
486
+ end
487
+ end
@@ -1,6 +1,6 @@
1
1
  module Calabash
2
2
  module Cucumber
3
- VERSION = "0.9.68"
4
- FRAMEWORK_VERSION = "0.9.65"
3
+ VERSION = "0.9.70"
4
+ FRAMEWORK_VERSION = "0.9.70"
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calabash-cucumber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.68
4
+ version: 0.9.70
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-06-20 00:00:00.000000000 Z
12
+ date: 2012-06-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cucumber
@@ -142,6 +142,7 @@ files:
142
142
  - features-skeleton/support/hooks.rb
143
143
  - features-skeleton/support/launch.rb
144
144
  - features/step_definitions/calabash_steps.rb
145
+ - features/step_definitions/my_first_steps.rb
145
146
  - lib/calabash-cucumber.rb
146
147
  - lib/calabash-cucumber/calabash_steps.rb
147
148
  - lib/calabash-cucumber/color_helper.rb
@@ -218,7 +219,7 @@ files:
218
219
  - scripts/data/.GlobalPreferences.plist
219
220
  - scripts/data/com.apple.Accessibility.plist
220
221
  - scripts/reset_simulator.scpt
221
- homepage: http://www.lesspainful.com/calabash
222
+ homepage: http://calaba.sh
222
223
  licenses: []
223
224
  post_install_message:
224
225
  rdoc_options: []
@@ -244,3 +245,4 @@ specification_version: 3
244
245
  summary: Client for calabash-ios-server for automated functional testing on iOS
245
246
  test_files:
246
247
  - features/step_definitions/calabash_steps.rb
248
+ - features/step_definitions/my_first_steps.rb