calabash-cucumber 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/dylibs/libCalabashDyn.dylib +0 -0
- data/dylibs/libCalabashDynSim.dylib +0 -0
- data/features-skeleton/support/01_launch.rb +1 -1
- data/features/step_definitions/calabash_steps.rb +114 -141
- data/lib/calabash-cucumber/device.rb +62 -19
- data/lib/calabash-cucumber/environment_helpers.rb +43 -23
- data/lib/calabash-cucumber/version.rb +3 -4
- data/scripts/launch.rb +1 -1
- data/staticlib/calabash.framework.zip +0 -0
- data/staticlib/libFrankCalabash.a +0 -0
- metadata +31 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffa8aea9b8e03a9601bed26f7a30ad9243dfb930
|
4
|
+
data.tar.gz: df96dc379a76662a9a2f1a2610e51a9027099b75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e981cc007418f8044f03ba925c79c3f71cc3c8dede0799c3b2629a0758ca5354d885b9ba82ce8152e62c10bf91fc13724d21fb943df84479238d32c442a3b46
|
7
|
+
data.tar.gz: 70e0f1c3188959ad2a45e34a4741fb6fed59f93544750bce3fb7c321da76f2513f6fe03a627a7ab07058fa08f190034070081c1bcea7b20f2b61ebab24b95d01
|
data/dylibs/libCalabashDyn.dylib
CHANGED
Binary file
|
Binary file
|
@@ -15,7 +15,7 @@
|
|
15
15
|
require 'calabash-cucumber/launcher'
|
16
16
|
|
17
17
|
|
18
|
-
# APP_BUNDLE_PATH = "
|
18
|
+
# APP_BUNDLE_PATH = "#{ENV['HOME']}/Library/Developer/Xcode/DerivedData/??/Build/Products/Calabash-iphonesimulator/??.app"
|
19
19
|
# You may uncomment the above to overwrite the APP_BUNDLE_PATH
|
20
20
|
# However the recommended approach is to let Calabash find the app itself
|
21
21
|
# or set the environment variable APP_BUNDLE_PATH
|
@@ -2,89 +2,85 @@ WAIT_TIMEOUT = (ENV['WAIT_TIMEOUT'] || 30).to_f
|
|
2
2
|
STEP_PAUSE = (ENV['STEP_PAUSE'] || 0.5).to_f
|
3
3
|
|
4
4
|
Given /^(my|the) app is running$/ do |_|
|
5
|
-
#no-op exists for backwards compatibility
|
5
|
+
# no-op exists for backwards compatibility
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
# -- Touch --#
|
8
|
+
### Touch ###
|
10
9
|
Then /^I (?:press|touch) on screen (\d+) from the left and (\d+) from the top$/ do |x, y|
|
11
|
-
touch(nil, {:
|
10
|
+
touch(nil, { offset: { x: x.to_i, y: y.to_i } })
|
12
11
|
sleep(STEP_PAUSE)
|
13
12
|
end
|
14
13
|
|
15
14
|
Then /^I (?:press|touch) "([^\"]*)"$/ do |name|
|
16
|
-
touch("view marked:'#{name}'")
|
15
|
+
touch("view marked: '#{name}'")
|
17
16
|
sleep(STEP_PAUSE)
|
18
17
|
end
|
19
18
|
|
20
|
-
Then /^I (?:press|touch) (\d+)% right and (\d+)% down from "([^\"]*)"$/ do |x,y,name|
|
21
|
-
raise
|
19
|
+
Then /^I (?:press|touch) (\d+)% right and (\d+)% down from "([^\"]*)"$/ do |x, y, name|
|
20
|
+
raise 'This step is not yet implemented on iOS'
|
22
21
|
end
|
23
22
|
|
24
23
|
Then /^I (?:press|touch) button number (\d+)$/ do |index|
|
25
24
|
index = index.to_i
|
26
|
-
screenshot_and_raise
|
27
|
-
touch("button index
|
25
|
+
screenshot_and_raise("Index should be positive (was: #{index})") if index <= 0
|
26
|
+
touch("button index: #{index - 1}")
|
28
27
|
sleep(STEP_PAUSE)
|
29
28
|
end
|
30
29
|
|
31
30
|
Then /^I (?:press|touch) the "([^\"]*)" button$/ do |name|
|
32
|
-
touch("button marked:'#{name}'")
|
31
|
+
touch("button marked: '#{name}'")
|
33
32
|
sleep(STEP_PAUSE)
|
34
33
|
end
|
35
34
|
|
36
35
|
Then /^I (?:press|touch) (?:input|text) field number (\d+)$/ do |index|
|
37
36
|
index = index.to_i
|
38
|
-
screenshot_and_raise
|
39
|
-
touch("textField index
|
40
|
-
sleep(STEP_PAUSE)
|
37
|
+
screenshot_and_raise("Index should be positive (was: #{index})") if index <= 0
|
38
|
+
touch("textField index: #{index - 1}")
|
39
|
+
sleep(STEP_PAUSE)
|
41
40
|
end
|
42
41
|
|
43
|
-
|
44
42
|
Then /^I (?:press|touch) the "([^\"]*)" (?:input|text) field$/ do |name|
|
45
|
-
placeholder_query = "textField placeholder:'#{name}'"
|
46
|
-
marked_query = "textField marked:'#{name}'"
|
43
|
+
placeholder_query = "textField placeholder: '#{name}'"
|
44
|
+
marked_query = "textField marked: '#{name}'"
|
47
45
|
if !query(placeholder_query).empty?
|
48
46
|
touch(placeholder_query)
|
49
47
|
elsif !query(marked_query).empty?
|
50
48
|
touch(marked_query)
|
51
49
|
else
|
52
|
-
screenshot_and_raise "
|
50
|
+
screenshot_and_raise "Could not find text field with placeholder '#{name}' or marked as '#{name}'"
|
53
51
|
end
|
54
52
|
sleep(STEP_PAUSE)
|
55
53
|
end
|
56
54
|
|
57
|
-
#Note in tables views: this means visible cell index!
|
55
|
+
# Note in tables views: this means visible cell index!
|
58
56
|
Then /^I (?:press|touch) list item number (\d+)$/ do |index|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
index = index.to_i
|
58
|
+
screenshot_and_raise("Index should be positive (was: #{index})") if index <= 0
|
59
|
+
touch("tableViewCell index: #{index - 1}")
|
60
|
+
sleep(STEP_PAUSE)
|
63
61
|
end
|
64
62
|
|
65
63
|
Then /^I (?:press|touch) list item "([^\"]*)"$/ do |cell_name|
|
66
|
-
if
|
67
|
-
|
68
|
-
then
|
69
|
-
touch("tableViewCell text:'#{cell_name}'")
|
64
|
+
if query("tableViewCell marked: '#{cell_name}'").empty?
|
65
|
+
touch("tableViewCell text:' #{cell_name}'")
|
70
66
|
else
|
71
|
-
touch("tableViewCell marked:'#{cell_name}'")
|
67
|
+
touch("tableViewCell marked: '#{cell_name}'")
|
72
68
|
end
|
73
69
|
sleep(STEP_PAUSE)
|
74
70
|
end
|
75
71
|
|
76
72
|
Then /^I toggle the switch$/ do
|
77
|
-
touch(
|
73
|
+
touch('switch')
|
78
74
|
sleep(STEP_PAUSE)
|
79
75
|
end
|
80
76
|
|
81
77
|
Then /^I toggle the "([^\"]*)" switch$/ do |name|
|
82
|
-
touch("switch marked:'#{name}'")
|
78
|
+
touch("switch marked: '#{name}'")
|
83
79
|
sleep(STEP_PAUSE)
|
84
80
|
end
|
85
81
|
|
86
82
|
Then /^I touch (?:the)? user location$/ do
|
87
|
-
touch("view:'MKUserLocationView'")
|
83
|
+
touch("view: 'MKUserLocationView'")
|
88
84
|
sleep(STEP_PAUSE)
|
89
85
|
end
|
90
86
|
|
@@ -93,54 +89,51 @@ Then /^I (?:touch|press) (?:done|search)$/ do
|
|
93
89
|
sleep(STEP_PAUSE)
|
94
90
|
end
|
95
91
|
|
96
|
-
|
97
|
-
## -- Entering text -- ##
|
98
|
-
|
92
|
+
### Entering text ###
|
99
93
|
Then /^I enter "([^\"]*)" into the "([^\"]*)" field$/ do |text_to_type, field_name|
|
100
|
-
touch("textField marked:'#{field_name}'")
|
101
|
-
wait_for_keyboard
|
94
|
+
touch("textField marked: '#{field_name}'")
|
95
|
+
wait_for_keyboard
|
102
96
|
keyboard_enter_text text_to_type
|
103
97
|
sleep(STEP_PAUSE)
|
104
98
|
end
|
105
99
|
|
106
100
|
Then /^I enter "([^\"]*)" into the "([^\"]*)" (?:text|input) field$/ do |text_to_type, field_name|
|
107
|
-
touch("textField marked:'#{field_name}'")
|
108
|
-
wait_for_keyboard
|
101
|
+
touch("textField marked: '#{field_name}'")
|
102
|
+
wait_for_keyboard
|
109
103
|
keyboard_enter_text text_to_type
|
110
104
|
sleep(STEP_PAUSE)
|
111
105
|
end
|
112
106
|
|
113
|
-
#
|
107
|
+
# Alias
|
114
108
|
Then /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |text_field, text_to_type|
|
115
|
-
macro %
|
109
|
+
macro %(I enter "#{text_to_type}" into the "#{text_field}" text field)
|
116
110
|
end
|
117
111
|
|
118
112
|
Then /^I use the native keyboard to enter "([^\"]*)" into the "([^\"]*)" (?:text|input) field$/ do |text_to_type, field_name|
|
119
|
-
macro %
|
120
|
-
wait_for_keyboard
|
113
|
+
macro %(I touch the "#{field_name}" text field)
|
114
|
+
wait_for_keyboard
|
121
115
|
keyboard_enter_text(text_to_type)
|
122
116
|
sleep(STEP_PAUSE)
|
123
117
|
end
|
124
118
|
|
125
119
|
Then /^I fill in text fields as follows:$/ do |table|
|
126
120
|
table.hashes.each do |row|
|
127
|
-
macro %
|
121
|
+
macro %(I enter "#{row['text']}" into the "#{row['field']}" text field)
|
128
122
|
end
|
129
123
|
end
|
130
124
|
|
131
125
|
Then /^I enter "([^\"]*)" into (?:input|text) field number (\d+)$/ do |text, index|
|
132
126
|
index = index.to_i
|
133
|
-
screenshot_and_raise
|
134
|
-
touch("textField index
|
135
|
-
wait_for_keyboard
|
127
|
+
screenshot_and_raise("Index should be positive (was: #{index})") if index <= 0
|
128
|
+
touch("textField index: #{index - 1}")
|
129
|
+
wait_for_keyboard
|
136
130
|
keyboard_enter_text text
|
137
131
|
sleep(STEP_PAUSE)
|
138
132
|
end
|
139
133
|
|
140
134
|
Then /^I use the native keyboard to enter "([^\"]*)" into (?:input|text) field number (\d+)$/ do |text_to_type, index|
|
141
|
-
|
142
|
-
|
143
|
-
wait_for_keyboard()
|
135
|
+
macro %(I touch text field number #{index})
|
136
|
+
wait_for_keyboard
|
144
137
|
keyboard_enter_text(text_to_type)
|
145
138
|
sleep(STEP_PAUSE)
|
146
139
|
end
|
@@ -148,61 +141,58 @@ end
|
|
148
141
|
When /^I clear "([^\"]*)"$/ do |name|
|
149
142
|
msg = "When I clear <name>' will be deprecated because it is ambiguous - what should be cleared?"
|
150
143
|
_deprecated('0.9.151', msg, :warn)
|
151
|
-
clear_text("textField marked:'#{name}'")
|
144
|
+
clear_text("textField marked: '#{name}'")
|
152
145
|
end
|
153
146
|
|
154
147
|
Then /^I clear (?:input|text) field number (\d+)$/ do |index|
|
155
148
|
index = index.to_i
|
156
|
-
screenshot_and_raise
|
157
|
-
clear_text("textField index
|
149
|
+
screenshot_and_raise("Index should be positive (was: #{index})") if index <= 0
|
150
|
+
clear_text("textField index: #{index - 1}")
|
158
151
|
end
|
159
152
|
|
160
|
-
|
153
|
+
### See ###
|
161
154
|
Then /^I wait to see "([^\"]*)"$/ do |expected_mark|
|
162
|
-
wait_for(WAIT_TIMEOUT) { view_with_mark_exists(
|
155
|
+
wait_for(WAIT_TIMEOUT) { view_with_mark_exists(expected_mark) }
|
163
156
|
end
|
164
157
|
|
165
158
|
Then /^I wait until I don't see "([^\"]*)"$/ do |expected_mark|
|
166
|
-
sleep 1
|
167
|
-
wait_for(WAIT_TIMEOUT) {
|
159
|
+
sleep 1 # wait for previous screen to disappear
|
160
|
+
wait_for(WAIT_TIMEOUT) { !element_exists("view marked: '#{expected_mark}'") }
|
168
161
|
end
|
169
162
|
|
170
163
|
Then /^I wait to not see "([^\"]*)"$/ do |expected_mark|
|
171
|
-
macro %
|
164
|
+
macro %(I wait until I don't see "#{expected_mark}")
|
172
165
|
end
|
173
166
|
|
174
167
|
Then /^I wait for "([^\"]*)" to appear$/ do |name|
|
175
|
-
macro %
|
168
|
+
macro %(I wait to see "#{name}")
|
176
169
|
end
|
177
170
|
|
178
171
|
Then /^I wait for the "([^\"]*)" button to appear$/ do |name|
|
179
|
-
wait_for(WAIT_TIMEOUT) { element_exists(
|
172
|
+
wait_for(WAIT_TIMEOUT) { element_exists("button marked: '#{name}'") }
|
180
173
|
end
|
181
174
|
|
182
175
|
Then /^I wait to see a navigation bar titled "([^\"]*)"$/ do |expected_mark|
|
183
|
-
msg = "
|
184
|
-
wait_for(:
|
185
|
-
|
186
|
-
|
187
|
-
button_items = query("navigationItemButtonView")
|
176
|
+
msg = "Waited for '#{WAIT_TIMEOUT}' seconds but did not see the navbar with title '#{expected_mark}'"
|
177
|
+
wait_for(timeout: WAIT_TIMEOUT, timeout_message: msg ) do
|
178
|
+
all_items = query("navigationItemView marked: '#{expected_mark}'")
|
179
|
+
button_items = query('navigationItemButtonView')
|
188
180
|
non_button_items = all_items.delete_if { |item| button_items.include?(item) }
|
189
181
|
!non_button_items.empty?
|
190
182
|
end
|
191
183
|
end
|
192
184
|
|
193
185
|
Then /^I wait for the "([^\"]*)" (?:input|text) field$/ do |placeholder_or_view_mark|
|
194
|
-
wait_for(WAIT_TIMEOUT)
|
195
|
-
element_exists(
|
196
|
-
|
197
|
-
|
186
|
+
wait_for(WAIT_TIMEOUT) do
|
187
|
+
element_exists("textField placeholder: '#{placeholder_or_view_mark}'") ||
|
188
|
+
element_exists("textField marked: '#{placeholder_or_view_mark}'")
|
189
|
+
end
|
198
190
|
end
|
199
191
|
|
200
192
|
Then /^I wait for (\d+) (?:input|text) field(?:s)?$/ do |count|
|
201
|
-
count
|
202
|
-
wait_for(WAIT_TIMEOUT) { query(:textField).count >= count }
|
193
|
+
wait_for(WAIT_TIMEOUT) { query(:textField).count >= count.to_i }
|
203
194
|
end
|
204
195
|
|
205
|
-
|
206
196
|
Then /^I wait$/ do
|
207
197
|
sleep 2
|
208
198
|
end
|
@@ -216,13 +206,11 @@ Then /^I wait and wait and wait...$/ do
|
|
216
206
|
end
|
217
207
|
|
218
208
|
When /^I wait for ([\d\.]+) second(?:s)?$/ do |num_seconds|
|
219
|
-
|
220
|
-
sleep num_seconds
|
209
|
+
sleep num_seconds.to_f
|
221
210
|
end
|
222
211
|
|
223
|
-
|
224
212
|
Then /^I go back$/ do
|
225
|
-
touch(
|
213
|
+
touch('navigationItemButtonView first')
|
226
214
|
sleep(STEP_PAUSE)
|
227
215
|
end
|
228
216
|
|
@@ -238,194 +226,179 @@ end
|
|
238
226
|
|
239
227
|
Then /^I swipe (left|right|up|down) on number (\d+)$/ do |dir, index|
|
240
228
|
index = index.to_i
|
241
|
-
screenshot_and_raise
|
242
|
-
swipe(dir, {:
|
229
|
+
screenshot_and_raise("Index should be positive (was: #{index})") if index <= 0
|
230
|
+
swipe(dir, { query: "scrollView index: #{index - 1}" })
|
243
231
|
sleep(STEP_PAUSE)
|
244
232
|
end
|
245
233
|
|
246
234
|
Then /^I swipe (left|right|up|down) on number (\d+) at x (\d+) and y (\d+)$/ do |dir, index, x, y|
|
247
235
|
index = index.to_i
|
248
|
-
screenshot_and_raise
|
249
|
-
swipe(dir, {:
|
236
|
+
screenshot_and_raise("Index should be positive (was: #{index})") if index <= 0
|
237
|
+
swipe(dir, { offset: { x: x.to_i, y: y.to_i }, query: "scrollView index: #{index - 1}" })
|
250
238
|
sleep(STEP_PAUSE)
|
251
239
|
end
|
252
240
|
|
253
241
|
Then /^I swipe (left|right|up|down) on "([^\"]*)"$/ do |dir, mark|
|
254
|
-
|
255
|
-
|
242
|
+
swipe(dir, { query: "view marked: '#{mark}'" })
|
243
|
+
sleep(STEP_PAUSE)
|
256
244
|
end
|
257
245
|
|
258
246
|
Then /^I swipe on cell number (\d+)$/ do |index|
|
259
247
|
index = index.to_i
|
260
|
-
screenshot_and_raise
|
261
|
-
cell_swipe({:
|
248
|
+
screenshot_and_raise("Index should be positive (was: #{index})") if index <= 0
|
249
|
+
cell_swipe({ query: "tableViewCell index: #{index - 1}" })
|
262
250
|
sleep(STEP_PAUSE)
|
263
251
|
end
|
264
252
|
|
265
|
-
|
266
|
-
##pinch##
|
253
|
+
### Pinch ###
|
267
254
|
Then /^I pinch to zoom (in|out)$/ do |in_out|
|
268
255
|
pinch(in_out)
|
269
256
|
sleep(STEP_PAUSE)
|
270
257
|
end
|
271
258
|
|
272
259
|
Then /^I pinch to zoom (in|out) on "([^\"]*)"$/ do |in_out, name|
|
273
|
-
pinch(in_out,{:
|
260
|
+
pinch(in_out, { query: "view marked: '#{name}'" })
|
274
261
|
sleep(STEP_PAUSE)
|
275
262
|
end
|
276
263
|
|
277
|
-
#
|
264
|
+
# Note "up/left/right" seems to be missing on the web base
|
278
265
|
Then /^I scroll (left|right|up|down)$/ do |dir|
|
279
|
-
scroll(
|
266
|
+
scroll('scrollView index: 0', dir)
|
280
267
|
sleep(STEP_PAUSE)
|
281
268
|
end
|
282
269
|
|
283
|
-
Then /^I scroll (left|right|up|down) on "([^\"]*)"$/ do |dir,name|
|
284
|
-
scroll("view marked:'#{name}'", dir)
|
270
|
+
Then /^I scroll (left|right|up|down) on "([^\"]*)"$/ do |dir, name|
|
271
|
+
scroll("view marked: '#{name}'", dir)
|
285
272
|
sleep(STEP_PAUSE)
|
286
273
|
end
|
287
274
|
|
288
|
-
|
289
|
-
|
290
275
|
### Playback ###
|
291
276
|
Then /^I playback recording "([^\"]*)"$/ do |filename|
|
292
|
-
|
293
|
-
|
277
|
+
playback(filename)
|
278
|
+
sleep(STEP_PAUSE)
|
294
279
|
end
|
295
280
|
|
296
281
|
Then /^I playback recording "([^\"]*)" on "([^\"]*)"$/ do |filename, name|
|
297
|
-
|
298
|
-
|
282
|
+
playback(filename, { query: "view marked: '#{name}'" })
|
283
|
+
sleep(STEP_PAUSE)
|
299
284
|
end
|
300
285
|
|
301
286
|
Then /^I playback recording "([^\"]*)" on "([^\"]*)" with offset (\d+),(\d+)$/ do |filename, name, x, y|
|
302
|
-
|
303
|
-
y = y.to_i
|
304
|
-
playback(filename, {:query => "view marked:'#{name}'", :offset => {:x => x, :y => y}})
|
287
|
+
playback(filename, { query: "view marked:'#{name}'", offset: { x: x.to_i, y: y.to_i } })
|
305
288
|
sleep(STEP_PAUSE)
|
306
289
|
end
|
307
290
|
|
308
291
|
Then /^I reverse playback recording "([^\"]*)"$/ do |filename|
|
309
|
-
playback(filename, {:
|
292
|
+
playback(filename, { reverse: true })
|
310
293
|
sleep(STEP_PAUSE)
|
311
294
|
end
|
312
295
|
|
313
296
|
Then /^I reverse playback recording "([^\"]*)" on "([^\"]*)"$/ do |filename, name|
|
314
|
-
playback(filename, {:
|
297
|
+
playback(filename, { query: "view marked: '#{name}'", reverse: true })
|
315
298
|
sleep(STEP_PAUSE)
|
316
299
|
end
|
317
300
|
|
318
301
|
Then /^I reverse playback recording "([^\"]*)" on "([^\"]*)" with offset (\d+),(\d+)$/ do |filename, name, x, y|
|
319
|
-
|
320
|
-
y = y.to_i
|
321
|
-
playback(filename, {:query => "view marked:'#{name}'", :offset => {:x => x, :y => y},:reverse => true})
|
302
|
+
playback(filename, { query: "view marked: '#{name}'", offset: { x: x.to_i, y: y.to_i }, reverse: true })
|
322
303
|
sleep(STEP_PAUSE)
|
323
304
|
end
|
324
305
|
|
325
|
-
|
326
306
|
### Device orientation ###
|
327
307
|
Then /^I rotate device (left|right)$/ do |dir|
|
328
|
-
dir
|
329
|
-
|
330
|
-
sleep(5)#SERVO wait
|
308
|
+
rotate(dir.to_sym)
|
309
|
+
sleep 5 # Servo wait
|
331
310
|
end
|
332
311
|
|
333
312
|
Then /^I send app to background for (\d+) seconds$/ do |secs|
|
334
313
|
secs = secs.to_f
|
335
314
|
send_app_to_background(secs)
|
336
|
-
sleep(secs+10)
|
315
|
+
sleep(secs + 10)
|
337
316
|
end
|
338
317
|
|
339
318
|
### Assertions ###
|
340
319
|
Then /^I should see "([^\"]*)"$/ do |expected_mark|
|
341
|
-
|
342
|
-
|
343
|
-
if not res
|
320
|
+
until element_exists("view marked:'#{expected_mark}'") ||
|
321
|
+
element_exists("view text:'#{expected_mark}'")
|
344
322
|
screenshot_and_raise "No element found with mark or text: #{expected_mark}"
|
345
323
|
end
|
346
324
|
end
|
347
325
|
|
348
326
|
Then /^I should not see "([^\"]*)"$/ do |expected_mark|
|
349
|
-
res = query("view marked:'#{expected_mark}'")
|
350
|
-
res.concat query("view text:'#{expected_mark}'")
|
327
|
+
res = query("view marked: '#{expected_mark}'")
|
328
|
+
res.concat query("view text: '#{expected_mark}'")
|
351
329
|
unless res.empty?
|
352
|
-
screenshot_and_raise "Expected no element with text nor accessibilityLabel: #{expected_mark}, found #{res.join(
|
330
|
+
screenshot_and_raise "Expected no element with text nor accessibilityLabel: #{expected_mark}, found #{res.join(', ')}"
|
353
331
|
end
|
354
332
|
end
|
355
333
|
|
356
334
|
Then /^I should see a "([^\"]*)" button$/ do |expected_mark|
|
357
|
-
check_element_exists("button marked:'#{expected_mark}'")
|
335
|
+
check_element_exists("button marked: '#{expected_mark}'")
|
358
336
|
end
|
359
337
|
Then /^I should not see a "([^\"]*)" button$/ do |expected_mark|
|
360
|
-
check_element_does_not_exist("button marked:'#{expected_mark}'")
|
338
|
+
check_element_does_not_exist("button marked: '#{expected_mark}'")
|
361
339
|
end
|
362
340
|
|
363
341
|
Then /^I don't see the text "([^\"]*)"$/ do |text|
|
364
|
-
macro %
|
342
|
+
macro %(I should not see "#{text}")
|
365
343
|
end
|
366
344
|
Then /^I don't see the "([^\"]*)"$/ do |text|
|
367
|
-
macro %
|
345
|
+
macro %(I should not see "#{text}")
|
368
346
|
end
|
369
347
|
|
370
348
|
Then /^I see the text "([^\"]*)"$/ do |text|
|
371
|
-
macro %
|
349
|
+
macro %(I should see "#{text}")
|
372
350
|
end
|
351
|
+
|
373
352
|
Then /^I see the "([^\"]*)"$/ do |text|
|
374
|
-
macro %
|
353
|
+
macro %(I should see "#{text}")
|
375
354
|
end
|
376
355
|
|
377
356
|
Then /^I (?:should)? see text starting with "([^\"]*)"$/ do |text|
|
378
|
-
|
379
|
-
if res
|
357
|
+
if query("view {text BEGINSWITH '#{text}'}").empty?
|
380
358
|
screenshot_and_raise "No text found starting with: #{text}"
|
381
359
|
end
|
382
360
|
end
|
383
361
|
|
384
362
|
Then /^I (?:should)? see text containing "([^\"]*)"$/ do |text|
|
385
|
-
|
386
|
-
if res
|
363
|
+
if query("view {text LIKE '*#{text}*'}").empty?
|
387
364
|
screenshot_and_raise "No text found containing: #{text}"
|
388
365
|
end
|
389
366
|
end
|
390
367
|
|
391
368
|
Then /^I (?:should)? see text ending with "([^\"]*)"$/ do |text|
|
392
|
-
|
393
|
-
if res
|
369
|
+
if query("view {text ENDSWITH '#{text}'}").empty?
|
394
370
|
screenshot_and_raise "No text found ending with: #{text}"
|
395
371
|
end
|
396
372
|
end
|
397
373
|
|
398
374
|
Then /^I see (\d+) (?:input|text) field(?:s)?$/ do |count|
|
399
|
-
count = count.to_i
|
400
375
|
cnt = query(:textField).count
|
401
|
-
if cnt < count
|
402
|
-
|
376
|
+
if cnt < count.to_i
|
377
|
+
screenshot_and_raise "Expected at least #{count} text/input fields, found #{cnt}"
|
403
378
|
end
|
404
379
|
end
|
405
380
|
|
406
381
|
Then /^I should see a "([^\"]*)" (?:input|text) field$/ do |expected_mark|
|
407
|
-
|
408
|
-
|
409
|
-
unless res
|
382
|
+
unless element_exists("textField placeholder: '#{expected_mark}'") ||
|
383
|
+
element_exists("textField marked: '#{expected_mark}'")
|
410
384
|
screenshot_and_raise "Expected textfield with placeholder or accessibilityLabel: #{expected_mark}"
|
411
385
|
end
|
412
386
|
end
|
413
387
|
|
414
388
|
Then /^I should not see a "([^\"]*)" (?:input|text) field$/ do |expected_mark|
|
415
|
-
res = query("textField placeholder:'#{expected_mark}'")
|
416
|
-
res.concat query("textField marked:'#{expected_mark}'")
|
389
|
+
res = query("textField placeholder: '#{expected_mark}'")
|
390
|
+
res.concat query("textField marked: '#{expected_mark}'")
|
417
391
|
unless res.empty?
|
418
392
|
screenshot_and_raise "Expected no textfield with placeholder nor accessibilityLabel: #{expected_mark}, found #{res}"
|
419
393
|
end
|
420
394
|
end
|
421
395
|
|
422
|
-
|
423
396
|
Then /^I should see a map$/ do
|
424
|
-
check_element_exists("view:'MKMapView'")
|
397
|
+
check_element_exists("view: 'MKMapView'")
|
425
398
|
end
|
426
399
|
|
427
400
|
Then /^I should see (?:the)? user location$/ do
|
428
|
-
check_element_exists("view:'MKUserLocationView'")
|
401
|
+
check_element_exists("view: 'MKUserLocationView'")
|
429
402
|
end
|
430
403
|
|
431
404
|
### Date Picker ###
|
@@ -433,7 +406,7 @@ end
|
|
433
406
|
# time_str can be in any format that Time can parse
|
434
407
|
Then(/^I change the date picker time to "([^"]*)"$/) do |time_str|
|
435
408
|
target_time = Time.parse(time_str)
|
436
|
-
current_date = date_time_from_picker
|
409
|
+
current_date = date_time_from_picker
|
437
410
|
current_date = DateTime.new(current_date.year,
|
438
411
|
current_date.mon,
|
439
412
|
current_date.day,
|
@@ -448,7 +421,7 @@ end
|
|
448
421
|
# date_str can be in any format that Date can parse
|
449
422
|
Then(/^I change the date picker date to "([^"]*)"$/) do |date_str|
|
450
423
|
target_date = Date.parse(date_str)
|
451
|
-
current_time = date_time_from_picker
|
424
|
+
current_time = date_time_from_picker
|
452
425
|
date_time = DateTime.new(target_date.year,
|
453
426
|
target_date.mon,
|
454
427
|
target_date.day,
|
@@ -463,6 +436,6 @@ end
|
|
463
436
|
|
464
437
|
# date_str can be in any format that Date can parse
|
465
438
|
Then(/^I change the date picker date to "([^"]*)" at "([^"]*)"$/) do |date_str, time_str|
|
466
|
-
macro %
|
467
|
-
macro %
|
439
|
+
macro %(I change the date picker time to "#{time_str}")
|
440
|
+
macro %(I change the date picker date to "#{date_str}")
|
468
441
|
end
|
@@ -108,15 +108,17 @@ module Calabash
|
|
108
108
|
# @return [Boolean] `true` if the app under test is emulated
|
109
109
|
attr_reader :iphone_app_emulated_on_ipad
|
110
110
|
|
111
|
-
#
|
112
|
-
# @attribute [r]
|
113
|
-
#
|
114
|
-
|
115
|
-
|
116
|
-
#
|
117
|
-
#
|
118
|
-
#
|
119
|
-
|
111
|
+
# The form factor of this device.
|
112
|
+
# @attribute [r] form_factor
|
113
|
+
#
|
114
|
+
# Will be one of:
|
115
|
+
# * ipad
|
116
|
+
# * iphone 4in
|
117
|
+
# * iphone 3.5in
|
118
|
+
# * iphone 6
|
119
|
+
# * iphone 6+
|
120
|
+
# * "" # if no information can be found.
|
121
|
+
attr_reader :form_factor
|
120
122
|
|
121
123
|
# For Calabash server version > 0.10.2 provides
|
122
124
|
# device specific screen information.
|
@@ -134,6 +136,17 @@ module Calabash
|
|
134
136
|
# @return [Hash] screen dimensions, scale and down/up sampling fraction.
|
135
137
|
attr_reader :screen_dimensions
|
136
138
|
|
139
|
+
# @deprecated 0.13.1 no replacement
|
140
|
+
# Indicates whether or not this device has a 4in screen.
|
141
|
+
# @attribute [r] iphone_4in
|
142
|
+
# @return [Boolean] `true` if this device has a 4in screen.
|
143
|
+
attr_reader :iphone_4in
|
144
|
+
|
145
|
+
# @deprecated 0.10.0 no replacement
|
146
|
+
# @!attribute [rw] udid
|
147
|
+
# @return [String] The udid of this device.
|
148
|
+
attr_accessor :udid
|
149
|
+
|
137
150
|
# Creates a new instance of Device.
|
138
151
|
#
|
139
152
|
# @see Calabash::Cucumber::Core#server_version
|
@@ -150,7 +163,6 @@ module Calabash
|
|
150
163
|
@ios_version = version_data['iOS_version']
|
151
164
|
@server_version = version_data['version']
|
152
165
|
@iphone_app_emulated_on_ipad = version_data['iphone_app_emulated_on_ipad']
|
153
|
-
@iphone_4in = version_data['4inch']
|
154
166
|
screen_dimensions = version_data['screen_dimensions']
|
155
167
|
if screen_dimensions
|
156
168
|
@screen_dimensions = {}
|
@@ -158,6 +170,10 @@ module Calabash
|
|
158
170
|
@screen_dimensions[key.to_sym] = val
|
159
171
|
end
|
160
172
|
end
|
173
|
+
@form_factor = version_data['form_factor']
|
174
|
+
|
175
|
+
# Deprecated 0.13.0
|
176
|
+
@iphone_4in = version_data['4inch']
|
161
177
|
end
|
162
178
|
|
163
179
|
# Is this device a simulator or physical device?
|
@@ -193,17 +209,25 @@ module Calabash
|
|
193
209
|
# Is this device a 4in iPhone?
|
194
210
|
# @return [Boolean] true if this device is a 4in iphone
|
195
211
|
def iphone_4in?
|
196
|
-
|
212
|
+
form_factor == 'iphone 4in'
|
197
213
|
end
|
198
214
|
|
199
|
-
#
|
200
|
-
# @
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
215
|
+
# Is this device an iPhone 6?
|
216
|
+
# @return [Boolean] true if this device is an iPhone 6
|
217
|
+
def iphone_6?
|
218
|
+
form_factor == 'iphone 6'
|
219
|
+
end
|
220
|
+
|
221
|
+
# Is this device an iPhone 6+?
|
222
|
+
# @return [Boolean] true if this device is an iPhone 6+
|
223
|
+
def iphone_6_plus?
|
224
|
+
form_factor == 'iphone 6+'
|
225
|
+
end
|
226
|
+
|
227
|
+
# Is this device an iPhone 3.5in?
|
228
|
+
# @return [Boolean] true if this device is an iPhone 3.5in?
|
229
|
+
def iphone_35in?
|
230
|
+
form_factor == 'iphone 3.5in'
|
207
231
|
end
|
208
232
|
|
209
233
|
# @!visibility private
|
@@ -289,6 +313,25 @@ module Calabash
|
|
289
313
|
_deprecated('0.10.0', 'no replacement', :warn)
|
290
314
|
@udid = value
|
291
315
|
end
|
316
|
+
|
317
|
+
# @deprecated 0.9.168 replaced with iphone_4in?
|
318
|
+
# @see #iphone_4in?
|
319
|
+
# Is this device an iPhone 5?
|
320
|
+
# @note Deprecated because the iPhone 5S reports as an iPhone6,*.
|
321
|
+
# @return [Boolean] true if this device is an iPhone 5
|
322
|
+
def iphone_5?
|
323
|
+
_deprecated('0.9.168', "use 'iphone_4in?' instead", :warn)
|
324
|
+
iphone_4in?
|
325
|
+
end
|
326
|
+
|
327
|
+
# @deprecated 0.13.1 - Call `iphone_4in?` instead.
|
328
|
+
# @see #iphone_4in?
|
329
|
+
# @note Deprecated after introducing new `form_factor` behavior.
|
330
|
+
# @return [Boolean] true if this device is an iPhone 5 or 5s
|
331
|
+
def iphone_4in
|
332
|
+
_deprecated('0.13.1', "use 'iphone_4in?' instead", :warn)
|
333
|
+
@iphone_4in
|
334
|
+
end
|
292
335
|
end
|
293
336
|
end
|
294
337
|
end
|
@@ -56,57 +56,71 @@ module Calabash
|
|
56
56
|
|
57
57
|
# Is the device under test an iPad?
|
58
58
|
#
|
59
|
-
# @raise [RuntimeError]
|
59
|
+
# @raise [RuntimeError] If the server cannot be reached.
|
60
60
|
# @return [Boolean] true if device under test is an iPad.
|
61
61
|
def ipad?
|
62
|
-
_default_device_or_create
|
62
|
+
_default_device_or_create.ipad?
|
63
63
|
end
|
64
64
|
|
65
65
|
# Is the device under test an iPhone?
|
66
66
|
#
|
67
|
-
# @raise [RuntimeError]
|
67
|
+
# @raise [RuntimeError] If the server cannot be reached.
|
68
68
|
# @return [Boolean] true if device under test is an iPhone.
|
69
69
|
def iphone?
|
70
|
-
_default_device_or_create
|
70
|
+
_default_device_or_create.iphone?
|
71
71
|
end
|
72
72
|
|
73
73
|
# Is the device under test an iPod?
|
74
74
|
#
|
75
|
-
# @raise [RuntimeError]
|
75
|
+
# @raise [RuntimeError] If the server cannot be reached.
|
76
76
|
# @return [Boolean] true if device under test is an iPod.
|
77
77
|
def ipod?
|
78
|
-
_default_device_or_create
|
78
|
+
_default_device_or_create.ipod?
|
79
79
|
end
|
80
80
|
|
81
81
|
# Is the device under test an iPhone or iPod?
|
82
82
|
#
|
83
|
-
# @raise [RuntimeError]
|
84
|
-
# @return [Boolean] true
|
83
|
+
# @raise [RuntimeError] If the server cannot be reached.
|
84
|
+
# @return [Boolean] true If device under test is an iPhone or iPod.
|
85
85
|
def device_family_iphone?
|
86
86
|
iphone? or ipod?
|
87
87
|
end
|
88
88
|
|
89
89
|
# Is the device under test a simulator?
|
90
90
|
#
|
91
|
-
# @raise [RuntimeError]
|
91
|
+
# @raise [RuntimeError] If the server cannot be reached.
|
92
92
|
# @return [Boolean] true if device under test is a simulator.
|
93
93
|
def simulator?
|
94
|
-
_default_device_or_create
|
95
|
-
end
|
96
|
-
|
97
|
-
# @deprecated 0.9.168 replaced with `iphone_4in?`
|
98
|
-
# @see #iphone_4in?
|
99
|
-
def iphone_5?
|
100
|
-
_deprecated('0.9.168', "use 'iphone_4in?' instead", :warn)
|
101
|
-
iphone_4in?
|
94
|
+
_default_device_or_create.simulator?
|
102
95
|
end
|
103
96
|
|
104
|
-
#
|
97
|
+
# Is the device under test have a 4 inch screen?
|
105
98
|
#
|
106
|
-
# @raise [RuntimeError]
|
99
|
+
# @raise [RuntimeError] If the server cannot be reached.
|
107
100
|
# @return [Boolean] true if device under test has a 4in screen.
|
108
101
|
def iphone_4in?
|
109
|
-
_default_device_or_create
|
102
|
+
_default_device_or_create.iphone_4in?
|
103
|
+
end
|
104
|
+
|
105
|
+
# Is the device under test an iPhone 6.
|
106
|
+
# @raise [RuntimeError] If the server cannot be reached.
|
107
|
+
# @return [Boolean] true if this device is an iPhone 6
|
108
|
+
def iphone_6?
|
109
|
+
_default_device_or_create.iphone_6?
|
110
|
+
end
|
111
|
+
|
112
|
+
# Is the device under test an iPhone 6+?
|
113
|
+
# @raise [RuntimeError] If the server cannot be reached.
|
114
|
+
# @return [Boolean] true if this device is an iPhone 6+
|
115
|
+
def iphone_6_plus?
|
116
|
+
_default_device_or_create.iphone_6_plus?
|
117
|
+
end
|
118
|
+
|
119
|
+
# Is the device under test an iPhone 3.5in?
|
120
|
+
# @raise [RuntimeError] If the server cannot be reached.
|
121
|
+
# @return [Boolean] true if this device is an iPhone 3.5in?
|
122
|
+
def iphone_35in?
|
123
|
+
_default_device_or_create.iphone_35in?
|
110
124
|
end
|
111
125
|
|
112
126
|
# Is the device under test running iOS 5?
|
@@ -139,7 +153,6 @@ module Calabash
|
|
139
153
|
_OS_ENV.eql?(_canonical_os_version(:ios6)) || _default_device_or_create().ios6?
|
140
154
|
end
|
141
155
|
|
142
|
-
|
143
156
|
# Is the device under test running iOS 7?
|
144
157
|
#
|
145
158
|
# @note
|
@@ -171,10 +184,17 @@ module Calabash
|
|
171
184
|
#
|
172
185
|
# @see Calabash::Cucumber::IPad
|
173
186
|
#
|
174
|
-
# @raise [RuntimeError]
|
187
|
+
# @raise [RuntimeError] If the server cannot be reached.
|
175
188
|
# @return [Boolean] true if app is being emulated on an iPad.
|
176
189
|
def iphone_app_emulated_on_ipad?
|
177
|
-
_default_device_or_create
|
190
|
+
_default_device_or_create.iphone_app_emulated_on_ipad?
|
191
|
+
end
|
192
|
+
|
193
|
+
# @deprecated 0.9.168 replaced with `iphone_4in?`
|
194
|
+
# @see #iphone_4in?
|
195
|
+
def iphone_5?
|
196
|
+
_deprecated('0.9.168', "use 'iphone_4in?' instead", :warn)
|
197
|
+
iphone_4in?
|
178
198
|
end
|
179
199
|
|
180
200
|
private
|
@@ -3,11 +3,10 @@ module Calabash
|
|
3
3
|
|
4
4
|
# @!visibility public
|
5
5
|
# The Calabash iOS gem version.
|
6
|
-
VERSION = '0.
|
6
|
+
VERSION = '0.14.0'
|
7
7
|
|
8
8
|
# @!visibility public
|
9
|
-
# The minimum required version of the
|
10
|
-
|
11
|
-
MIN_SERVER_VERSION = '0.13.0'
|
9
|
+
# The minimum required version of the Calabash embedded server.
|
10
|
+
MIN_SERVER_VERSION = '0.14.0'
|
12
11
|
end
|
13
12
|
end
|
data/scripts/launch.rb
CHANGED
@@ -17,7 +17,7 @@
|
|
17
17
|
require 'calabash-cucumber/launcher'
|
18
18
|
|
19
19
|
|
20
|
-
# APP_BUNDLE_PATH = "
|
20
|
+
# APP_BUNDLE_PATH = "#{ENV['HOME']}/Library/Developer/Xcode/DerivedData/??/Build/Products/Calabash-iphonesimulator/??.app"
|
21
21
|
# You may uncomment the above to overwrite the APP_BUNDLE_PATH
|
22
22
|
# However the recommended approach is to let Calabash find the app itself
|
23
23
|
# or set the environment variable APP_BUNDLE_PATH
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: calabash-cucumber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Karl Krukow
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cucumber
|
@@ -144,16 +144,22 @@ dependencies:
|
|
144
144
|
name: run_loop
|
145
145
|
requirement: !ruby/object:Gem::Requirement
|
146
146
|
requirements:
|
147
|
-
- - "
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '1.3'
|
150
|
+
- - "<"
|
148
151
|
- !ruby/object:Gem::Version
|
149
|
-
version:
|
152
|
+
version: '2.0'
|
150
153
|
type: :runtime
|
151
154
|
prerelease: false
|
152
155
|
version_requirements: !ruby/object:Gem::Requirement
|
153
156
|
requirements:
|
154
|
-
- - "
|
157
|
+
- - ">="
|
155
158
|
- !ruby/object:Gem::Version
|
156
|
-
version: 1.
|
159
|
+
version: '1.3'
|
160
|
+
- - "<"
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '2.0'
|
157
163
|
- !ruby/object:Gem::Dependency
|
158
164
|
name: json
|
159
165
|
requirement: !ruby/object:Gem::Requirement
|
@@ -224,6 +230,20 @@ dependencies:
|
|
224
230
|
- - '='
|
225
231
|
- !ruby/object:Gem::Version
|
226
232
|
version: 3.2.0
|
233
|
+
- !ruby/object:Gem::Dependency
|
234
|
+
name: luffa
|
235
|
+
requirement: !ruby/object:Gem::Requirement
|
236
|
+
requirements:
|
237
|
+
- - ">="
|
238
|
+
- !ruby/object:Gem::Version
|
239
|
+
version: '0'
|
240
|
+
type: :development
|
241
|
+
prerelease: false
|
242
|
+
version_requirements: !ruby/object:Gem::Requirement
|
243
|
+
requirements:
|
244
|
+
- - ">="
|
245
|
+
- !ruby/object:Gem::Version
|
246
|
+
version: '0'
|
227
247
|
- !ruby/object:Gem::Dependency
|
228
248
|
name: rake
|
229
249
|
requirement: !ruby/object:Gem::Requirement
|
@@ -326,16 +346,16 @@ dependencies:
|
|
326
346
|
name: stub_env
|
327
347
|
requirement: !ruby/object:Gem::Requirement
|
328
348
|
requirements:
|
329
|
-
- -
|
349
|
+
- - ">="
|
330
350
|
- !ruby/object:Gem::Version
|
331
|
-
version: 0
|
351
|
+
version: '0'
|
332
352
|
type: :development
|
333
353
|
prerelease: false
|
334
354
|
version_requirements: !ruby/object:Gem::Requirement
|
335
355
|
requirements:
|
336
|
-
- -
|
356
|
+
- - ">="
|
337
357
|
- !ruby/object:Gem::Version
|
338
|
-
version: 0
|
358
|
+
version: '0'
|
339
359
|
description: calabash-cucumber drives tests for native iOS apps. You must link your
|
340
360
|
app with calabash-ios-server framework to execute tests.
|
341
361
|
email:
|
@@ -531,7 +551,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
531
551
|
version: '0'
|
532
552
|
requirements: []
|
533
553
|
rubyforge_project:
|
534
|
-
rubygems_version: 2.
|
554
|
+
rubygems_version: 2.4.5
|
535
555
|
signing_key:
|
536
556
|
specification_version: 4
|
537
557
|
summary: Client for calabash-ios-server for automated functional testing on iOS
|