calabash 2.0.0.pre11 → 2.0.0.prelegacy

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.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -5
  3. data/bin/calabash +4 -3
  4. data/lib/calabash/android/adb.rb +37 -34
  5. data/lib/calabash/android/application.rb +1 -1
  6. data/lib/calabash/android/build/builder.rb +1 -1
  7. data/lib/calabash/android/build/java_keystore.rb +1 -1
  8. data/lib/calabash/android/build/resigner.rb +1 -1
  9. data/lib/calabash/android/device.rb +46 -204
  10. data/lib/calabash/android/environment.rb +1 -14
  11. data/lib/calabash/android/gestures.rb +22 -6
  12. data/lib/calabash/android/interactions.rb +17 -14
  13. data/lib/calabash/android/legacy.rb +141 -4
  14. data/lib/calabash/android/lib/.irbrc +1 -9
  15. data/lib/calabash/android/lib/AndroidManifest.xml +2 -23
  16. data/lib/calabash/android/lib/TestServer.apk +0 -0
  17. data/lib/calabash/android/life_cycle.rb +3 -3
  18. data/lib/calabash/android/orientation.rb +8 -8
  19. data/lib/calabash/android/physical_buttons.rb +16 -19
  20. data/lib/calabash/android/server.rb +1 -6
  21. data/lib/calabash/android/text.rb +12 -12
  22. data/lib/calabash/android.rb +26 -92
  23. data/lib/calabash/application.rb +0 -3
  24. data/lib/calabash/cli/generate.rb +18 -8
  25. data/lib/calabash/cli/helpers.rb +9 -4
  26. data/lib/calabash/cli/run.rb +1 -1
  27. data/lib/calabash/console_helpers.rb +11 -179
  28. data/lib/calabash/device.rb +19 -4
  29. data/lib/calabash/gestures.rb +198 -292
  30. data/lib/calabash/http/retriable_client.rb +3 -18
  31. data/lib/calabash/http.rb +0 -1
  32. data/lib/calabash/interactions.rb +40 -3
  33. data/lib/calabash/ios/conditions.rb +1 -1
  34. data/lib/calabash/ios/console_helpers.rb +2 -2
  35. data/lib/calabash/ios/date_picker.rb +8 -10
  36. data/lib/calabash/ios/device/device_implementation.rb +21 -9
  37. data/lib/calabash/ios/device/gestures_mixin.rb +55 -53
  38. data/lib/calabash/ios/device/keyboard_mixin.rb +0 -21
  39. data/lib/calabash/ios/device/rotation_mixin.rb +65 -3
  40. data/lib/calabash/ios/device/text_mixin.rb +21 -0
  41. data/lib/calabash/ios/device.rb +1 -0
  42. data/lib/calabash/ios/gestures.rb +90 -24
  43. data/lib/calabash/ios/interactions.rb +6 -1
  44. data/lib/calabash/ios/lib/.irbrc +2 -9
  45. data/lib/calabash/ios/orientation.rb +8 -8
  46. data/lib/calabash/ios/runtime.rb +14 -14
  47. data/lib/calabash/ios/scroll.rb +17 -25
  48. data/lib/calabash/ios/slider.rb +18 -11
  49. data/lib/calabash/ios/text.rb +74 -20
  50. data/lib/calabash/ios/uia.rb +1 -1
  51. data/lib/calabash/ios.rb +16 -77
  52. data/lib/calabash/legacy.rb +6 -9
  53. data/lib/calabash/lib/skeleton/{Gemfile.skeleton → Gemfile} +0 -0
  54. data/lib/calabash/lib/skeleton/config/{cucumber.yml.skeleton → cucumber.yml} +0 -0
  55. data/lib/calabash/lib/skeleton/features/{sample.feature.skeleton → sample.feature} +0 -0
  56. data/lib/calabash/lib/skeleton/features/step_definitions/{sample_steps.rb.skeleton → calabash_steps.rb} +8 -8
  57. data/lib/calabash/lib/skeleton/features/support/{dry_run.rb.skeleton → dry_run.rb} +5 -2
  58. data/lib/calabash/lib/skeleton/features/support/{env.rb.skeleton → env.rb} +8 -2
  59. data/lib/calabash/lib/skeleton/features/support/hooks.rb +83 -0
  60. data/lib/calabash/life_cycle.rb +8 -16
  61. data/lib/calabash/location.rb +15 -14
  62. data/lib/calabash/orientation.rb +8 -8
  63. data/lib/calabash/page.rb +4 -1
  64. data/lib/calabash/screenshot.rb +3 -3
  65. data/lib/calabash/text.rb +19 -31
  66. data/lib/calabash/utility.rb +8 -41
  67. data/lib/calabash/version.rb +1 -1
  68. data/lib/calabash/wait.rb +192 -177
  69. data/lib/calabash.rb +10 -53
  70. metadata +32 -43
  71. data/lib/calabash/android/device/helper_application.rb +0 -95
  72. data/lib/calabash/android/lib/HelperApplication.apk +0 -0
  73. data/lib/calabash/android/lib/HelperApplicationTestServer.apk +0 -0
  74. data/lib/calabash/android/web.rb +0 -12
  75. data/lib/calabash/http/forwarding_client.rb +0 -23
  76. data/lib/calabash/internal.rb +0 -48
  77. data/lib/calabash/ios/automator/automator.rb +0 -217
  78. data/lib/calabash/ios/automator/coordinates.rb +0 -37
  79. data/lib/calabash/ios/automator/device_agent.rb +0 -379
  80. data/lib/calabash/ios/automator.rb +0 -9
  81. data/lib/calabash/ios/legacy.rb +0 -6
  82. data/lib/calabash/ios/web.rb +0 -10
  83. data/lib/calabash/lib/skeleton/features/support/hooks.rb.skeleton +0 -34
  84. data/lib/calabash/retry.rb +0 -33
  85. data/lib/calabash/stubs.rb +0 -21
  86. data/lib/calabash/web.rb +0 -44
@@ -1,217 +0,0 @@
1
- module Calabash
2
- module IOS
3
- # @!visibility private
4
- module Automator
5
- # @!visibility private
6
- class Automator
7
- include Utility
8
-
9
- # @!visibility private
10
- def initialize(*args)
11
- abstract_method!
12
- end
13
-
14
- # @!visibility private
15
- def name
16
- abstract_method!
17
- end
18
-
19
- # @!visibility private
20
- def stop
21
- abstract_method!
22
- end
23
-
24
- # @!visibility private
25
- def running?
26
- abstract_method!
27
- end
28
-
29
- # @!visibility private
30
- def client
31
- abstract_method!
32
- end
33
-
34
- # @!visibility private
35
- def touch(options)
36
- abstract_method!
37
- end
38
-
39
- # @!visibility private
40
- def double_tap(options)
41
- abstract_method!
42
- end
43
-
44
- # @!visibility private
45
- def two_finger_tap(options)
46
- abstract_method!
47
- end
48
-
49
- # @!visibility private
50
- def touch_hold(options)
51
- abstract_method!
52
- end
53
-
54
- # @!visibility private
55
- def flick(options)
56
- abstract_method!
57
- end
58
-
59
- # @!visibility private
60
- def pan(options={})
61
- abstract_method!
62
- end
63
-
64
- # @!visibility private
65
- #
66
- # Callers must validate the options.
67
- def pan_coordinates(from_point, to_point, options={})
68
- abstract_method!
69
- end
70
-
71
- # @!visibility private
72
- #
73
- # Callers must validate the options.
74
- def pinch(in_or_out, options)
75
- abstract_method!
76
- end
77
-
78
- # @!visibility private
79
- def send_app_to_background(seconds)
80
- abstract_method!
81
- end
82
-
83
- # @!visibility private
84
- #
85
- # It is the caller's responsibility to:
86
- # 1. expect the keyboard is visible
87
- # 2. escape the existing text
88
- def enter_text_with_keyboard(string, options={})
89
- abstract_method!
90
- end
91
-
92
- # @!visibility private
93
- #
94
- # Respond to keys like 'Delete' or 'Return'.
95
- def char_for_keyboard_action(action_key)
96
- abstract_method!
97
- end
98
-
99
- # @!visibility private
100
- # It is the caller's responsibility to ensure the keyboard is visible.
101
- def enter_char_with_keyboard(char)
102
- abstract_method!
103
- end
104
-
105
- # @!visibility private
106
- # It is the caller's responsibility to ensure the keyboard is visible.
107
- def tap_keyboard_action_key(return_key_type_of_first_responder)
108
- abstract_method!
109
- end
110
-
111
- # @!visibility private
112
- # It is the caller's responsibility to ensure the keyboard is visible.
113
- def tap_keyboard_delete_key
114
- abstract_method!
115
- end
116
-
117
- # @!visibility private
118
- #
119
- # Legacy API - can we remove this method?
120
- #
121
- # It is the caller's responsibility to ensure the keyboard is visible.
122
- def fast_enter_text(text)
123
- abstract_method!
124
- end
125
-
126
- # @!visibility private
127
- #
128
- # Caller is responsible for limiting calls to iPads and waiting for the
129
- # keyboard to disappear.
130
- def dismiss_ipad_keyboard
131
- abstract_method!
132
- end
133
-
134
- # @!visibility private
135
- #
136
- # Caller is responsible for providing a valid direction.
137
- def rotate(direction, status_bar_orientation)
138
- abstract_method!
139
- end
140
-
141
- # @!visibility private
142
- #
143
- # Caller is responsible for normalizing and validating the position.
144
- def rotate_home_button_to(position, status_bar_orientation)
145
- abstract_method!
146
- end
147
-
148
- # @! visibility private
149
- #
150
- # It is important to remember that the current orientation is the
151
- # position of the home button:
152
- #
153
- # :up => home button on the top => upside_down
154
- # :bottom => home button on the bottom => portrait
155
- # :left => home button on the left => landscape_right
156
- # :right => home button on the right => landscape_left
157
- #
158
- # Notice how :left and :right are mapped.
159
- def self.orientation_key(direction, current_orientation)
160
- key = nil
161
- case direction
162
- when :left then
163
- if current_orientation == :down
164
- key = :landscape_left
165
- elsif current_orientation == :right
166
- key = :upside_down
167
- elsif current_orientation == :left
168
- key = :portrait
169
- elsif current_orientation == :up
170
- key = :landscape_right
171
- end
172
- when :right then
173
- if current_orientation == :down
174
- key = :landscape_right
175
- elsif current_orientation == :right
176
- key = :portrait
177
- elsif current_orientation == :left
178
- key = :upside_down
179
- elsif current_orientation == :up
180
- key = :landscape_left
181
- end
182
- else
183
- raise ArgumentError,
184
- "Expected '#{direction}' to be :left or :right"
185
- end
186
-
187
- key
188
- end
189
-
190
- # @!visibility private
191
- def self.orientation_for_key(key)
192
- DEVICE_ORIENTATION[key]
193
- end
194
-
195
- # @! visibility private
196
- #
197
- # It is important to remember that the current orientation is the
198
- # position of the home button:
199
- #
200
- # :up => home button on the top => upside_down
201
- # :bottom => home button on the bottom => portrait
202
- # :left => home button on the left => landscape_right
203
- # :right => home button on the right => landscape_left
204
- #
205
- # Notice how :left and :right are mapped to their logical opposite.
206
- # @!visibility private
207
- # @! visibility private
208
- DEVICE_ORIENTATION = {
209
- :portrait => 1,
210
- :upside_down => 2,
211
- :landscape_left => 3, # Home button on the right
212
- :landscape_right => 4 # Home button on the left
213
- }.freeze
214
- end
215
- end
216
- end
217
- end
@@ -1,37 +0,0 @@
1
- module Calabash
2
- module IOS
3
- # @!visibility private
4
- module Automator
5
- # @!visibility private
6
- class Coordinates
7
- # @!visibility private
8
- def self.end_point_for_swipe(dir, element)
9
- case dir
10
- when :left
11
- degrees = 0
12
- when :up
13
- degrees = 90
14
- when :right
15
- degrees = 180
16
- when :down
17
- degrees = 270
18
- end
19
- radians = degrees * Math::PI / 180.0
20
-
21
- element_width = element["rect"]["width"]
22
- element_height = element["rect"]["height"]
23
- x_center = element["rect"]["center_x"]
24
- y_center = element["rect"]["center_y"]
25
- radius = ([element_width, element_height].min) * 0.33
26
- to_x = x_center - (radius * Math.cos(radians))
27
- to_y = y_center - (radius * Math.sin(radians))
28
- {:x => to_x, :y => to_y}
29
- end
30
-
31
- def self.distance(from, to)
32
- Math.sqrt((from[:x] - to[:x]) ** 2 + (from[:y] - to[:y]) ** 2)
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,379 +0,0 @@
1
- require "run_loop"
2
-
3
- module Calabash
4
- module IOS
5
- # @!visibility private
6
- module Automator
7
- # @!visibility private
8
- class DeviceAgent < Calabash::IOS::Automator::Automator
9
-
10
- # @!visibility private
11
- def self.expect_valid_args(args)
12
- if args.nil?
13
- raise ArgumentError, "Expected args to be a non-nil Array"
14
- end
15
-
16
- if !args.is_a?(Array)
17
- raise ArgumentError, %Q[Expected args to be an Array, found:
18
-
19
- args = #{args}
20
-
21
- ]
22
- end
23
-
24
- if args.count != 1
25
- raise(ArgumentError,
26
- %Q[Expected args to be an Array with one element, found:
27
-
28
- args = #{args}
29
-
30
- ])
31
- end
32
-
33
- if !args[0].is_a?(RunLoop::DeviceAgent::Client)
34
- raise(ArgumentError, %Q[
35
- Expected first element of args to be a RunLoop::DeviceAgent::Client instance, found:
36
- args[0] = #{args[0]}])
37
- end
38
-
39
- true
40
- end
41
-
42
- attr_reader :client
43
-
44
- # @!visibility private
45
- def initialize(*args)
46
- DeviceAgent.expect_valid_args(args)
47
- @client = args[0]
48
- end
49
-
50
- # @!visibility private
51
- def name
52
- :device_agent
53
- end
54
-
55
- # @!visibility private
56
- def stop
57
- client.send(:shutdown)
58
- end
59
-
60
- # @!visibility private
61
- def running?
62
- client.send(:running?)
63
- end
64
-
65
- # @!visibility private
66
- def session_delete
67
- client.send(:session_delete)
68
- end
69
-
70
- # @!visibility private
71
- def touch(options)
72
- client.perform_coordinate_gesture("touch",
73
- options[:coordinates][:x],
74
- options[:coordinates][:y])
75
- end
76
-
77
- # @!visibility private
78
- def double_tap(options)
79
- client.perform_coordinate_gesture("double_tap",
80
- options[:coordinates][:x],
81
- options[:coordinates][:y])
82
- end
83
-
84
- # @!visibility private
85
- def two_finger_tap(options)
86
- client.perform_coordinate_gesture("two_finger_tap",
87
- options[:coordinates][:x],
88
- options[:coordinates][:y])
89
- end
90
-
91
- # @!visibility private
92
- def touch_hold(options)
93
- client.perform_coordinate_gesture("touch",
94
- options[:coordinates][:x],
95
- options[:coordinates][:y],
96
- {:duration => options[:duration]})
97
- end
98
-
99
- # @!visibility private
100
- def pinch(in_out, options)
101
- dupped_options = options.dup
102
-
103
- if dupped_options[:query].nil?
104
- element = element_for_device_screen
105
- coordinates = point_from(element, options)
106
- else
107
- hash = query_for_coordinates(dupped_options)
108
- element = hash[:view]
109
- coordinates = hash[:coordinates]
110
- end
111
-
112
- in_out = in_out.to_s
113
- duration = dupped_options[:duration]
114
- amount = dupped_options[:amount]
115
-
116
- gesture_options = {
117
- :pinch_direction => in_out,
118
- :amount => amount,
119
- :duration => duration
120
- }
121
-
122
- client.perform_coordinate_gesture("pinch",
123
- coordinates[:x],
124
- coordinates[:y],
125
- gesture_options)
126
-
127
- [element]
128
- end
129
-
130
- MIN_SECONDS_PR_PIXEL_FOR_PAN = 0.006
131
-
132
- # @!visibility private
133
- def pan(options)
134
- # A pan seems to require 0.005 seconds pr. pixel.
135
- # Therefore we require that the duration is at least
136
- # 0.005 seconds pr pixel.
137
-
138
- duration = [
139
- options[:duration],
140
- MIN_SECONDS_PR_PIXEL_FOR_PAN *
141
- Coordinates.distance(options[:coordinates][:from], options[:coordinates][:to])
142
- ].max
143
-
144
- client.pan_between_coordinates(options[:coordinates][:from],
145
- options[:coordinates][:to],
146
- {:duration => duration})
147
- end
148
-
149
- # @!visibility private
150
- def flick(options)
151
- gesture_options = {
152
- duration: 0.2
153
- }
154
-
155
- delta = options[:delta]
156
-
157
- # The UIA deltas are too small.
158
- scaled_delta = {
159
- :x => delta[:x] * 2.0,
160
- :y => delta[:y] * 2.0
161
- }
162
-
163
- hash = query_for_coordinates(options)
164
- view = hash[:view]
165
-
166
- start_point = point_from(view)
167
- end_point = point_from(view, {:offset => scaled_delta})
168
-
169
- client.pan_between_coordinates(start_point,
170
- end_point,
171
- gesture_options)
172
- [view]
173
- end
174
-
175
- # @!visibility private
176
- def enter_text_with_keyboard(string, options={})
177
- client.enter_text(string)
178
- end
179
-
180
- # @!visibility private
181
- def enter_char_with_keyboard(char)
182
- client.enter_text(char)
183
- end
184
-
185
- # @!visibility private
186
- def char_for_keyboard_action(action_key)
187
- SPECIAL_ACTION_CHARS[action_key]
188
- end
189
-
190
- # @!visibility private
191
- def tap_keyboard_action_key(return_key_type_of_first_responder)
192
- mark = mark_for_return_key_of_first_responder(return_key_type_of_first_responder)
193
- if mark
194
- begin
195
- # The underlying query for coordinates always expects results.
196
- value = client.touch({marked: mark})
197
- return value
198
- rescue RuntimeError => _
199
- RunLoop.log_debug("Cannot find mark '#{mark}' with query; will send a newline")
200
- end
201
- else
202
- RunLoop.log_debug("Cannot find keyboard return key type; sending a newline")
203
- end
204
-
205
- code = char_for_keyboard_action("Return")
206
- client.enter_text(code)
207
- end
208
-
209
- # @!visibility private
210
- def tap_keyboard_delete_key
211
- client.touch({marked: "delete"})
212
- end
213
-
214
- # @!visibility private
215
- def fast_enter_text(text)
216
- client.enter_text(text)
217
- end
218
-
219
- # @!visibility private
220
- #
221
- # Stable across different keyboard languages.
222
- def dismiss_ipad_keyboard
223
- client.touch({marked: "Hide keyboard"})
224
- end
225
-
226
- # @!visibility private
227
- def rotate(direction, status_bar_orientation)
228
- # Caller is responsible for normalizing and verifying direction.
229
- current_orientation = status_bar_orientation.to_sym
230
- key = Automator.orientation_key(direction, current_orientation)
231
- position = Automator.orientation_for_key(key)
232
- rotate_home_button_to(position, status_bar_orientation)
233
- end
234
-
235
- # @!visibility private
236
- def rotate_home_button_to(position, status_bar_orientation)
237
- # Caller is responsible for normalizing and verifying position.
238
- client.rotate_home_button_to(position)
239
- status_bar_orientation.to_sym
240
- end
241
-
242
- private
243
-
244
- # @!visibility private
245
- #
246
- # Calls #point_from which applies any :offset supplied in the options.
247
- def query_for_coordinates(options)
248
- uiquery = options[:query]
249
-
250
- if uiquery.nil?
251
- offset = options[:offset]
252
-
253
- if offset && offset[:x] && offset[:y]
254
- {
255
- :coordinates => offset,
256
- :view => offset
257
- }
258
- else
259
- raise ArgumentError, %Q[
260
- If query is nil, there must be a valid offset in the options.
261
-
262
- Expected: options[:offset] = {:x => NUMERIC, :y => NUMERIC}
263
- Actual: options[:offset] = #{offset ? offset : "nil"}
264
-
265
- ]
266
- end
267
- else
268
-
269
- first_element = first_element_for_query(uiquery)
270
-
271
- if first_element.nil?
272
- msg = %Q[
273
- Could not find any views with query:
274
-
275
- #{uiquery}
276
-
277
- Make sure your query returns at least one view.
278
-
279
- ]
280
- Calabash::Cucumber::Map.new.screenshot_and_raise(msg)
281
- else
282
- {
283
- :coordinates => point_from(first_element, options),
284
- :view => first_element
285
- }
286
- end
287
- end
288
- end
289
-
290
- # @!visibility private
291
- def first_element_for_query(uiquery)
292
-
293
- if uiquery.nil?
294
- raise ArgumentError, "Query cannot be nil"
295
- end
296
-
297
- # Will raise if response "outcome" is not SUCCESS
298
- results = Calabash::Cucumber::Map.raw_map(uiquery, :query)["results"]
299
-
300
- if results.empty?
301
- nil
302
- else
303
- results[0]
304
- end
305
- end
306
-
307
- # @!visibility private
308
- def element_for_device_screen
309
- screen_dimensions = device.screen_dimensions
310
-
311
- scale = screen_dimensions[:scale]
312
- height = (screen_dimensions[:height]/scale).to_i
313
- center_y = (height/2)
314
- width = (screen_dimensions[:width]/scale).to_i
315
- center_x = (width/2)
316
-
317
- {
318
- "screen" => true,
319
- "rect" => {
320
- "height" => height,
321
- "width" => width,
322
- "center_x" => center_x,
323
- "center_y" => center_y
324
- }
325
- }
326
- end
327
-
328
- # @!visibility private
329
- #
330
- # Don't change the double quotes.
331
- SPECIAL_ACTION_CHARS = {
332
- "Delete" => "\b",
333
- "Return" => "\n"
334
- }.freeze
335
-
336
- # @!visibility private
337
- #
338
- # Keys are from the UIReturnKeyType enum.
339
- #
340
- # The values are localization independent identifiers - these are
341
- # stable across localizations and keyboard languages. The exception is
342
- # Continue which is not stable.
343
- RETURN_KEY_TYPE = {
344
- 0 => "Return",
345
- 1 => "Go",
346
- 2 => "Google",
347
- # Needs special physical device vs simulator handling.
348
- 3 => "Join",
349
- 4 => "Next",
350
- 5 => "Route",
351
- 6 => "Search",
352
- 7 => "Send",
353
- 8 => "Yahoo",
354
- 9 => "Done",
355
- 10 => "Emergency call",
356
- # https://xamarin.atlassian.net/browse/TCFW-344
357
- # Localized!!! Apple bug.
358
- 11 => "Continue"
359
- }.freeze
360
-
361
- # @!visibility private
362
- def mark_for_return_key_type(number)
363
- # https://xamarin.atlassian.net/browse/TCFW-361
364
- value = RETURN_KEY_TYPE[number]
365
- if value == "Join" && !simulator?
366
- "Join:"
367
- else
368
- value
369
- end
370
- end
371
-
372
- # @!visibility private
373
- def mark_for_return_key_of_first_responder(return_key_type_of_first_responder)
374
- mark_for_return_key_type(return_key_type_of_first_responder)
375
- end
376
- end
377
- end
378
- end
379
- end
@@ -1,9 +0,0 @@
1
- module Calabash
2
- module IOS
3
- module Automator
4
- require 'calabash/ios/automator/automator'
5
- require 'calabash/ios/automator/coordinates'
6
- require 'calabash/ios/automator/device_agent'
7
- end
8
- end
9
- end
@@ -1,6 +0,0 @@
1
- if Calabash::Environment.variable('DEVICE_ENDPOINT')
2
- Calabash::Logger.warn("Deprecated use of old ENV variable 'DEVICE_ENDPOINT'")
3
-
4
- Calabash::IOS::Environment::DEVICE_ENDPOINT =
5
- URI.parse(Calabash::Environment.variable('DEVICE_ENDPOINT'))
6
- end
@@ -1,10 +0,0 @@
1
- module Calabash
2
- module IOS
3
- module Web
4
- # @!visibility private
5
- define_method(:_evaluate_javascript_in) do |query, javascript|
6
- query(query, calabashStringByEvaluatingJavaScript: javascript)
7
- end
8
- end
9
- end
10
- end
@@ -1,34 +0,0 @@
1
- require 'calabash'
2
-
3
- Before do |scenario|
4
- if scenario.respond_to?(:scenario_outline)
5
- scenario = scenario.scenario_outline
6
- end
7
-
8
- reset_between_scenarios(scenario) do
9
- cal.reset_device_changes # Resets changes Calabash has made to the device
10
- cal.ensure_app_installed # Installs the app unless it is already installed
11
- cal.clear_app_data # Clears the application data
12
- cal.start_app # Starts the application
13
- end
14
- end
15
-
16
- After do |scenario|
17
- if scenario.failed?
18
- cal.screenshot_embed
19
- end
20
-
21
- cal.stop_app
22
- end
23
-
24
- def reset_between_scenarios(scenario, &block)
25
- block.call
26
- end
27
-
28
- def reset_between_features(scenario, &block)
29
- if scenario.feature != @last_feature
30
- block.call
31
- end
32
-
33
- @last_feature = scenario.feature
34
- end