calabash-cucumber 0.9.6 → 0.9.8

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.
@@ -0,0 +1,15 @@
1
+ require 'irb/completion'
2
+ require 'irb/ext/save-history'
3
+
4
+ ARGV.concat [ "--readline",
5
+ "--prompt-mode",
6
+ "simple" ]
7
+
8
+ # 25 entries in the list
9
+ IRB.conf[:SAVE_HISTORY] = 50
10
+
11
+ # Store results in home directory with specified file name
12
+ IRB.conf[:HISTORY_FILE] = ".irb-history"
13
+
14
+ require 'calabash-cucumber/operations'
15
+ include Calabash::Cucumber::Operations
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ IRBRC=.irbrc OS=ios4 DEVICE=iphone irb
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ IRBRC=.irbrc OS=ios5 DEVICE=iphone irb
@@ -1,5 +1,5 @@
1
1
  WAIT_TIMEOUT = ENV['WAIT_TIMEOUT'] || 30
2
- STEP_PAUSE = ENV['STEP_PAUSE'].to_f || 0.3
2
+ STEP_PAUSE = (ENV['STEP_PAUSE'] || 0.5).to_f
3
3
 
4
4
  require 'rspec/expectations'
5
5
 
@@ -9,40 +9,39 @@ end
9
9
 
10
10
 
11
11
  # -- Touch --#
12
- Then /^I (press|touch) on screen (\d+) from the left and (\d+) from the top$/ do |_, x, y|
13
- touch(nil, {:x => x, :y => y})
12
+ Then /^I (?:press|touch) on screen (\d+) from the left and (\d+) from the top$/ do |x, y|
13
+ touch(nil, {:x => x.to_i, :y => y.to_i})
14
14
  sleep(STEP_PAUSE)
15
15
  end
16
16
 
17
- Then /^I (press|touch) "([^\"]*)"$/ do |_,name|
17
+ Then /^I (?:press|touch) "([^\"]*)"$/ do |name|
18
18
  touch("view marked:'#{name}'")
19
-
20
19
  sleep(STEP_PAUSE)
21
20
  end
22
21
 
23
- #Then /^I (press|touch) (\d+)% right and (\d+)% down from "([^\"]*)" $/ do |_,x,y,name|
24
- # touch({:query => "view marked:'#{name}'", :offset => {:x => x, :y => y}})
25
- #end
22
+ Then /^I (?:press|touch) (\d+)% right and (\d+)% down from "([^\"]*)" $/ do |x,y,name|
23
+ raise "This step is not yet implemented on iOS"
24
+ end
26
25
 
27
- Then /^I (press|touch) button number (\d+)$/ do |_,index|
26
+ Then /^I (?:press|touch) button number (\d+)$/ do |index|
28
27
  index = index.to_i
29
28
  screenshot_and_raise "Index should be positive (was: #{index})" if (index<=0)
30
29
  touch("button index:#{index-1}")
31
30
  sleep(STEP_PAUSE)
32
31
  end
33
32
 
34
- Then /^I (press|touch) the "([^\"]*)" button$/ do |_,name|
33
+ Then /^I (?:press|touch) the "([^\"]*)" button$/ do |name|
35
34
  touch("button marked:'#{name}'")
36
35
  sleep(STEP_PAUSE)
37
36
  end
38
37
 
39
- # /^I press view with name "([^\"]*)"$/
40
- # like touch "..."
41
- # /^I press image button number (\d+)$/
42
- # iOS doesn't have image buttons'
38
+ Then /^I (?:press|touch) the "([^\"]*)" (?:input|text) field$/ do |name|
39
+ touch("textField placeholder:'#{name}'")
40
+ sleep(STEP_PAUSE)
41
+ end
43
42
 
44
- ##TODO note in tables views: this means visible cell index!
45
- Then /^I (press|touch) list item number (\d+)$/ do |_,index|
43
+ #Note in tables views: this means visible cell index!
44
+ Then /^I (?:press|touch) list item number (\d+)$/ do |index|
46
45
  index = index.to_i
47
46
  screenshot_and_raise "Index should be positive (was: #{index})" if (index<=0)
48
47
  touch("tableViewCell index:#{index-1}")
@@ -50,101 +49,115 @@ Then /^I (press|touch) list item number (\d+)$/ do |_,index|
50
49
  end
51
50
 
52
51
  Then /^I toggle the switch$/ do
53
- touch("view:'UISwitch'")
52
+ touch("switch")
54
53
  sleep(STEP_PAUSE)
55
54
  end
56
55
 
57
56
  Then /^I toggle the "([^\"]*)" switch$/ do |name|
58
- touch("view:'UISwitch' marked:'#{name}'")
57
+ touch("switch marked:'#{name}'")
58
+ sleep(STEP_PAUSE)
59
+ end
60
+
61
+ Then /^I touch (?:the)? user location$/ do
62
+ touch("view:'MKUserLocationView'")
63
+ sleep(STEP_PAUSE)
64
+ end
65
+
66
+ Then /^I (?:touch|press) (?:done|search)$/ do
67
+ done
59
68
  sleep(STEP_PAUSE)
60
69
  end
61
70
 
62
- #/^I enter "([^\"]*)" as "([^\"]*)"$/
63
- ## -- Entering text directly --##
64
- When /^I enter "([^\"]*)" into the "([^\"]*)" text field$/ do |text_to_type, field_name|
71
+
72
+ ## -- Entering text -- ##
73
+ Then /^I enter "([^\"]*)" into the "([^\"]*)" (?:text|input) field$/ do |text_to_type, field_name|
65
74
  set_text("textField placeholder:'#{field_name}'", text_to_type)
66
75
  sleep(STEP_PAUSE)
67
76
  end
68
77
 
69
78
  # alias
70
- When /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |text_field, text_to_type|
79
+ Then /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |text_field, text_to_type|
71
80
  When %Q|I enter "#{text_to_type}" into the "#{text_field}" text field|
72
81
  end
73
82
 
74
- When /^I fill in text fields as follows:$/ do |table|
83
+ Then /^I use the native keyboard to enter "([^\"]*)" into the "([^\"]*)" (?:text|input) field$/ do |text_to_type, field_name|
84
+ raise "Native keyboard entering is not yet implemented on iOS"
85
+ end
86
+
87
+ Then /^I fill in text fields as follows:$/ do |table|
75
88
  table.hashes.each do |row|
76
- When %Q|I enter "#{row['text']}" into the "#{row['field']}" text field|
89
+ macro %Q|I enter "#{row['text']}" into the "#{row['field']}" text field|
77
90
  end
78
91
  end
79
92
 
80
- Then /^I enter "([^\"]*)" into input field number (\d+)$/ do |text, index|
93
+ Then /^I enter "([^\"]*)" into (?:input|text) field number (\d+)$/ do |text, index|
81
94
  index = index.to_i
82
95
  screenshot_and_raise "Index should be positive (was: #{index})" if (index<=0)
83
96
  set_text("textField index:#{index-1}",text)
84
- sleep(STEP_PAUSE)
85
97
  end
86
98
 
99
+ Then /^I use the native keyboard to enter "([^\"]*)" into (?:input|text) field number (\d+)$/ do |text, index|
100
+ raise "Native keyboard entering is not yet implemented on iOS"
101
+ end
102
+
103
+
87
104
  When /^I clear "([^\"]*)"$/ do |name|
88
- When %Q|I enter "" into the "#{name}" text field|
105
+ macro %Q|I enter "" into the "#{name}" text field|
89
106
  end
90
107
 
91
108
  Then /^I clear input field number (\d+)$/ do |index|
92
109
  index = index.to_i
93
110
  screenshot_and_raise "Index should be positive (was: #{index})" if (index<=0)
94
111
  set_text("textField index:#{index-1}","")
95
- sleep(STEP_PAUSE)
96
112
  end
97
113
 
98
-
99
-
100
-
101
114
  # -- See -- #
102
115
  Then /^I wait to see "([^\"]*)"$/ do |expected_mark|
103
- Timeout::timeout(WAIT_TIMEOUT) do
104
- until view_with_mark_exists( expected_mark )
105
- sleep 0.3
106
- end
107
- end
116
+ wait_for(WAIT_TIMEOUT) { view_with_mark_exists( expected_mark ) }
117
+ end
118
+
119
+ Then /^I wait until I don't see "([^\"]*)"$/ do |expected_mark|
120
+ sleep 1## wait for previous screen to disappear
121
+ wait_for(WAIT_TIMEOUT) { not element_exists( "view marked:'#{expected_mark}'" )}
108
122
  end
109
123
 
110
124
  Then /^I wait to not see "([^\"]*)"$/ do |expected_mark|
111
- sleep 2
112
- Timeout::timeout(WAIT_TIMEOUT) do
113
- while element_exists( "view marked:'#{expected_mark}'" )
114
- sleep 0.3
115
- end
116
- end
125
+ macro %Q|I wait until I don't see "#{expected_mark}"|
117
126
  end
118
127
 
119
128
  Then /^I wait for "([^\"]*)" to appear$/ do |name|
120
129
  macro %Q|I wait to see "#{name}"|
121
130
  end
122
131
 
123
- When /^I wait for ([\d\.]+) second(?:s)?$/ do |num_seconds|
124
- num_seconds = num_seconds.to_f
125
- sleep num_seconds
132
+ Then /^I wait for the "([^\"]*)" button to appear$/ do |name|
133
+ wait_for(WAIT_TIMEOUT) { element_exists( "button marked:'#{name}'" ) }
126
134
  end
127
- #/^I wait for dialog to close$/
128
- #/^I wait for progress$/
129
135
 
130
136
  Then /^I wait for the "([^\"]*)" button to appear$/ do |name|
131
- Timeout::timeout(WAIT_TIMEOUT) do
132
- until element_exists( "button marked:'#{name}'" )
133
- sleep 0.3
134
- end
135
- end
137
+ wait_for(WAIT_TIMEOUT) {element_exists( "button marked:'#{name}'" )}
136
138
  end
137
139
 
140
+
138
141
  Then /^I wait to see a navigation bar titled "([^\"]*)"$/ do |expected_mark|
139
- Timeout::timeout(30) do
140
- values = query('navigationItemView', :accessibilityLabel)
141
- until values.include?(expected_mark)
142
- values = query('navigationItemView', :accessibilityLabel)
143
- sleep 0.3
144
- end
145
- end
142
+ wait_for(WAIT_TIMEOUT) do
143
+ query('navigationItemView', :accessibilityLabel).include?(expected_mark)
144
+ end
146
145
  end
147
146
 
147
+ Then /^I wait for the "([^\"]*)" button to appear$/ do |name|
148
+ wait_for(WAIT_TIMEOUT) { element_exists( "button marked:'#{name}'" ) }
149
+ end
150
+
151
+ Then /^I wait for the "([^\"]*)" (?:input|text) field$/ do |placeholder|
152
+ wait_for(WAIT_TIMEOUT) { element_exists( "textField placeholder:'#{placeholder}'") }
153
+ end
154
+
155
+ Then /^I wait for (\d+) (?:input|text) field(?:s)?$/ do |count|
156
+ count = count.to_i
157
+ wait_for(WAIT_TIMEOUT) { query(:textField).count >= count }
158
+ end
159
+
160
+
148
161
  Then /^I wait$/ do
149
162
  sleep 2
150
163
  end
@@ -157,9 +170,15 @@ Then /^I wait and wait and wait\.\.\.$/ do
157
170
  sleep 10
158
171
  end
159
172
 
173
+ When /^I wait for ([\d\.]+) second(?:s)?$/ do |num_seconds|
174
+ num_seconds = num_seconds.to_f
175
+ sleep num_seconds
176
+ end
177
+
178
+
160
179
  Then /^I go back$/ do
161
- touch("navigationItemButtonView first")
162
- sleep(STEP_PAUSE)
180
+ touch("navigationItemButtonView first")
181
+ sleep(STEP_PAUSE)
163
182
  end
164
183
 
165
184
  Then /^take picture$/ do
@@ -167,14 +186,12 @@ Then /^take picture$/ do
167
186
  screenshot
168
187
  end
169
188
 
170
- # Note "up/down" seems to be missing on the web page?
171
- # Should be /^I swipe (left|right|up|down)$/
172
- Then /^I swipe (left|right)$/ do |dir|
189
+ Then /^I swipe (left|right|up|down)$/ do |dir|
173
190
  swipe(dir)
174
191
  sleep(STEP_PAUSE)
175
192
  end
176
193
 
177
- Then /^I swipe (left|right) on "([^\"]*)"$/ do |dir, mark|
194
+ Then /^I swipe (left|right|up|down) on "([^\"]*)"$/ do |dir, mark|
178
195
  swipe(dir, {:query => "view marked:'#{mark}'"})
179
196
  sleep(STEP_PAUSE)
180
197
  end
@@ -186,16 +203,15 @@ Then /^I swipe on cell number (\d+)$/ do |index|
186
203
  sleep(STEP_PAUSE)
187
204
  end
188
205
 
189
-
190
206
  ##pinch##
191
207
  Then /^I pinch to zoom (in|out)$/ do |in_out|
192
208
  pinch(in_out)
193
- sleep([STEP_PAUSE+4,6].max)
209
+ sleep(STEP_PAUSE)
194
210
  end
195
211
 
196
212
  Then /^I pinch to zoom (in|out) on "([^\"]*)"$/ do |in_out, name|
197
213
  pinch(in_out,{:query => "view marked:'#{name}'"})
198
- sleep([STEP_PAUSE+4,6].max)
214
+ sleep(STEP_PAUSE)
199
215
  end
200
216
 
201
217
  # Note "up/left/right" seems to be missing on the web page
@@ -230,13 +246,13 @@ Then /^I playback recording "([^"]*) on "([^"]*)" with offset (\d+),(\d+)$/ do |
230
246
  end
231
247
 
232
248
  Then /^I reverse playback recording "([^"]*)"$/ do |filename|
233
- playback(filename, {:reverse => true})
234
- sleep(STEP_PAUSE)
249
+ playback(filename, {:reverse => true})
250
+ sleep(STEP_PAUSE)
235
251
  end
236
252
 
237
253
  Then /^I reverse playback recording "([^"]*) on "([^"]*)"$/ do |filename, name|
238
- playback(filename, {:query => "view marked:'#{name}'",:reverse => true})
239
- sleep(STEP_PAUSE)
254
+ playback(filename, {:query => "view marked:'#{name}'",:reverse => true})
255
+ sleep(STEP_PAUSE)
240
256
  end
241
257
 
242
258
  Then /^I reverse playback recording "([^"]*) on "([^"]*)" with offset (\d+),(\d+)$/ do |filename, name, x, y|
@@ -251,23 +267,27 @@ end
251
267
  Then /^I rotate device (left|right)$/ do |dir|
252
268
  dir = dir.to_sym
253
269
  rotate(dir)
254
- sleep(STEP_PAUSE)
270
+ sleep(5)#SERVO wait
255
271
  end
256
272
 
257
273
  Then /^I send app to background for (\d+) seconds$/ do |secs|
258
274
  secs = secs.to_f
259
275
  background(secs)
276
+ sleep(secs+10)
260
277
  end
261
278
 
262
279
  ### Assertions ###
263
280
  Then /^I should see "([^\"]*)"$/ do |expected_mark|
264
281
  res = (element_exists( "view marked:'#{expected_mark}'" ) ||
265
282
  element_exists( "view text:'#{expected_mark}'"))
266
- res.should be_true
283
+ if not res
284
+ screenshot_and_raise "No element found with mark or text: #{expected_mark}"
285
+ end
267
286
  end
268
287
 
269
288
  Then /^I should not see "([^\"]*)"$/ do |expected_mark|
270
- check_element_does_not_exist("view marked:'#{expected_mark}'")
289
+ check_element_does_not_exist("view marked:'#{expected_mark}'") &&
290
+ check_element_does_not_exist("view text:'#{expected_mark}'")
271
291
  end
272
292
 
273
293
  Then /^I should see a "([^\"]*)" button$/ do |expected_mark|
@@ -291,17 +311,43 @@ Then /^I see the "([^\"]*)"$/ do |text|
291
311
  macro %Q|I should see "#{text}"|
292
312
  end
293
313
 
314
+ Then /^I see text starting with "([^\"]*)"$/ do |text|
315
+ res = query("view {text BEGINSWITH '#{text}'}").empty?
316
+ if res
317
+ screenshot_and_raise "No text found starting with: #{text}"
318
+ end
319
+ end
294
320
 
295
- Then /^I should see a map$/ do
296
- check_element_exists("view:'MKMapView'")
321
+ Then /^I see text ending with "([^\"]*)"$/ do |text|
322
+ res = query("view {text ENDSWITH '#{text}'}").empty?
323
+ if res
324
+ screenshot_and_raise "No text found ending with: #{text}"
325
+ end
297
326
  end
298
327
 
299
- Then /^I touch user location$/ do
300
- touch("view:'MKUserLocationView'")
328
+ Then /^I see (\d+) (?:input|text) field(?:s)?$/ do |count|
329
+ count = count.to_i
330
+ cnt = query(:textField).count
331
+ if cnt < count
332
+ screenshot_and_raise "Expected at least #{count} text/input fields, found #{cnt}"
333
+ end
301
334
  end
302
335
 
303
- Then /^I (touch|press) (done|search)$/ do |_,__|
304
- done
305
- sleep(STEP_PAUSE)
336
+ Then /^I should see a "([^\"]*)" (?:input|text) field$/ do |expected_mark|
337
+ check_element_exists("textField placeholder:'#{expected_mark}'") ||
338
+ check_element_exists("textField marked:'#{expected_mark}'")
339
+ end
340
+
341
+ Then /^I should not see a "([^\"]*)" (?:input|text) field$/ do |expected_mark|
342
+ check_element_does_not_exist("textField placeholder:'#{expected_mark}'") &&
343
+ check_element_does_not_exist("textField marked:'#{expected_mark}'")
306
344
  end
307
345
 
346
+
347
+ Then /^I should see a map$/ do
348
+ check_element_exists("view:'MKMapView'")
349
+ end
350
+
351
+ Then /^I should see (?:the)? user location$/ do
352
+ check_element_exists("view:'MKUserLocationView'")
353
+ end
@@ -1,6 +1,14 @@
1
1
  require 'net/http/persistent'
2
2
  require 'json'
3
3
 
4
+ if not Object.const_defined?(:CALABASH_COUNT)
5
+ #compatability with IRB
6
+ CALABASH_COUNT = {:step_index => 0, :step_line => "irb"}
7
+ end
8
+
9
+
10
+
11
+
4
12
  module Calabash module Cucumber
5
13
 
6
14
  module Operations
@@ -15,10 +23,22 @@ module Operations
15
23
  end
16
24
  end
17
25
 
26
+ def wait_for(timeout, &block)
27
+ Timeout::timeout(timeout) do
28
+ until block.call
29
+ sleep 0.3
30
+ end
31
+ end
32
+ end
33
+
18
34
  def query(uiquery, *args)
19
35
  map(uiquery, :query, *args)
20
36
  end
21
37
 
38
+ def label(uiquery)
39
+ query(uiquery, :accessibilityLabel)
40
+ end
41
+
22
42
  def screenshot_and_raise(msg)
23
43
  screenshot
24
44
  sleep 5
@@ -124,7 +144,7 @@ module Operations
124
144
  end
125
145
 
126
146
  def background(secs)
127
- screenshot_and_raise "Not implemented yet"
147
+ res = http({:method=>:post, :path=>'background'}, {:duration => secs})
128
148
  end
129
149
 
130
150
  def element_exists(uiquery)
@@ -136,11 +156,15 @@ module Operations
136
156
  end
137
157
 
138
158
  def check_element_exists( query )
139
- element_exists( query ).should be_true
159
+ if not element_exists( query )
160
+ screenshot_and_raise "No element found for query: #{query}"
161
+ end
140
162
  end
141
163
 
142
164
  def check_element_does_not_exist( query )
143
- element_exists( query ).should be_false
165
+ if not element_exists( query ).should be_false
166
+ screenshot_and_raise "Expected no elements to match query: #{query}"
167
+ end
144
168
  end
145
169
 
146
170
  def check_view_with_mark_exists(expected_mark)
@@ -1,5 +1,5 @@
1
1
  module Calabash
2
2
  module Cucumber
3
- VERSION = "0.9.6"
3
+ VERSION = "0.9.8"
4
4
  end
5
5
  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.6
4
+ version: 0.9.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-27 00:00:00.000000000 Z
12
+ date: 2012-02-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cucumber
16
- requirement: &70312339656540 !ruby/object:Gem::Requirement
16
+ requirement: &70106252462660 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70312339656540
24
+ version_requirements: *70106252462660
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70312339655440 !ruby/object:Gem::Requirement
27
+ requirement: &70106252462080 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 2.7.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70312339655440
35
+ version_requirements: *70106252462080
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: json
38
- requirement: &70312339654480 !ruby/object:Gem::Requirement
38
+ requirement: &70106252461540 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70312339654480
46
+ version_requirements: *70106252461540
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: slowhandcuke
49
- requirement: &70312339644820 !ruby/object:Gem::Requirement
49
+ requirement: &70106252460880 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70312339644820
57
+ version_requirements: *70106252460880
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: net-http-persistent
60
- requirement: &70312339644160 !ruby/object:Gem::Requirement
60
+ requirement: &70106252460180 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70312339644160
68
+ version_requirements: *70106252460180
69
69
  description: calabash-cucumber drives tests for native iOS apps. You must link your
70
70
  app with calabash-ios-server framework to execute tests.
71
71
  email:
@@ -86,6 +86,9 @@ files:
86
86
  - calabash-cucumber.gemspec
87
87
  - copy_resources.sh
88
88
  - epl-v10.html
89
+ - features-skeleton/.irbrc
90
+ - features-skeleton/irb_ios4.sh
91
+ - features-skeleton/irb_ios5.sh
89
92
  - features-skeleton/my_first.feature
90
93
  - features-skeleton/step_definitions/calabash_steps.rb
91
94
  - features-skeleton/support/env.rb