calabash 2.0.0.pre10 → 2.0.0.pre11

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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -17
  3. data/bin/calabash +3 -4
  4. data/lib/calabash.rb +53 -10
  5. data/lib/calabash/android.rb +89 -28
  6. data/lib/calabash/android/adb.rb +32 -20
  7. data/lib/calabash/android/application.rb +1 -1
  8. data/lib/calabash/android/build/builder.rb +1 -1
  9. data/lib/calabash/android/build/java_keystore.rb +1 -1
  10. data/lib/calabash/android/build/resigner.rb +1 -1
  11. data/lib/calabash/android/device.rb +22 -66
  12. data/lib/calabash/android/device/helper_application.rb +95 -0
  13. data/lib/calabash/android/environment.rb +14 -1
  14. data/lib/calabash/android/gestures.rb +6 -22
  15. data/lib/calabash/android/interactions.rb +14 -17
  16. data/lib/calabash/android/lib/.irbrc +9 -1
  17. data/lib/calabash/android/lib/AndroidManifest.xml +23 -2
  18. data/lib/calabash/android/lib/HelperApplication.apk +0 -0
  19. data/lib/calabash/android/lib/HelperApplicationTestServer.apk +0 -0
  20. data/lib/calabash/android/lib/TestServer.apk +0 -0
  21. data/lib/calabash/android/life_cycle.rb +3 -3
  22. data/lib/calabash/android/orientation.rb +8 -8
  23. data/lib/calabash/android/physical_buttons.rb +19 -16
  24. data/lib/calabash/android/server.rb +1 -1
  25. data/lib/calabash/android/text.rb +12 -12
  26. data/lib/calabash/android/web.rb +12 -0
  27. data/lib/calabash/application.rb +3 -0
  28. data/lib/calabash/cli/generate.rb +8 -18
  29. data/lib/calabash/cli/helpers.rb +4 -9
  30. data/lib/calabash/cli/run.rb +1 -1
  31. data/lib/calabash/console_helpers.rb +179 -11
  32. data/lib/calabash/device.rb +4 -19
  33. data/lib/calabash/gestures.rb +292 -198
  34. data/lib/calabash/interactions.rb +3 -40
  35. data/lib/calabash/internal.rb +48 -0
  36. data/lib/calabash/ios.rb +76 -16
  37. data/lib/calabash/ios/automator.rb +9 -0
  38. data/lib/calabash/ios/automator/automator.rb +217 -0
  39. data/lib/calabash/ios/automator/coordinates.rb +37 -0
  40. data/lib/calabash/ios/automator/device_agent.rb +379 -0
  41. data/lib/calabash/ios/conditions.rb +1 -1
  42. data/lib/calabash/ios/console_helpers.rb +2 -2
  43. data/lib/calabash/ios/date_picker.rb +10 -8
  44. data/lib/calabash/ios/device.rb +0 -1
  45. data/lib/calabash/ios/device/device_implementation.rb +9 -21
  46. data/lib/calabash/ios/device/gestures_mixin.rb +53 -55
  47. data/lib/calabash/ios/device/keyboard_mixin.rb +21 -0
  48. data/lib/calabash/ios/device/rotation_mixin.rb +3 -65
  49. data/lib/calabash/ios/gestures.rb +24 -90
  50. data/lib/calabash/ios/interactions.rb +1 -6
  51. data/lib/calabash/ios/lib/.irbrc +9 -2
  52. data/lib/calabash/ios/orientation.rb +8 -8
  53. data/lib/calabash/ios/runtime.rb +14 -14
  54. data/lib/calabash/ios/scroll.rb +25 -17
  55. data/lib/calabash/ios/slider.rb +11 -18
  56. data/lib/calabash/ios/text.rb +20 -74
  57. data/lib/calabash/ios/uia.rb +1 -1
  58. data/lib/calabash/ios/web.rb +10 -0
  59. data/lib/calabash/lib/skeleton/{Gemfile → Gemfile.skeleton} +0 -0
  60. data/lib/calabash/lib/skeleton/config/{cucumber.yml → cucumber.yml.skeleton} +0 -0
  61. data/lib/calabash/lib/skeleton/features/{sample.feature → sample.feature.skeleton} +0 -0
  62. data/lib/calabash/lib/skeleton/features/step_definitions/{calabash_steps.rb → sample_steps.rb.skeleton} +8 -8
  63. data/lib/calabash/lib/skeleton/features/support/{dry_run.rb → dry_run.rb.skeleton} +2 -5
  64. data/lib/calabash/lib/skeleton/features/support/{env.rb → env.rb.skeleton} +2 -8
  65. data/lib/calabash/lib/skeleton/features/support/hooks.rb.skeleton +34 -0
  66. data/lib/calabash/life_cycle.rb +16 -8
  67. data/lib/calabash/location.rb +14 -15
  68. data/lib/calabash/orientation.rb +8 -8
  69. data/lib/calabash/page.rb +1 -4
  70. data/lib/calabash/retry.rb +33 -0
  71. data/lib/calabash/screenshot.rb +3 -3
  72. data/lib/calabash/stubs.rb +21 -0
  73. data/lib/calabash/text.rb +31 -19
  74. data/lib/calabash/utility.rb +41 -8
  75. data/lib/calabash/version.rb +1 -1
  76. data/lib/calabash/wait.rb +177 -192
  77. data/lib/calabash/web.rb +44 -0
  78. metadata +39 -32
  79. data/lib/calabash/ios/device/text_mixin.rb +0 -21
  80. data/lib/calabash/lib/skeleton/features/support/hooks.rb +0 -83
@@ -5,7 +5,7 @@ module Calabash
5
5
  include Utility
6
6
 
7
7
  # @!visibility private
8
- @@default = nil
8
+ @@default ||= nil
9
9
 
10
10
  # @!visibility private
11
11
  def self.default
@@ -180,29 +180,14 @@ module Calabash
180
180
  # @see Calabash::Gestures#pan
181
181
  # @!visibility private
182
182
  def pan(query, from, to, options={})
183
- Query.ensure_valid_query(query)
184
-
185
- ensure_valid_swipe_params(from, to)
186
-
187
- gesture_options = options.dup
188
- gesture_options[:duration] ||= 0.5
189
- gesture_options[:timeout] ||= Calabash::Gestures::DEFAULT_GESTURE_WAIT_TIMEOUT
190
-
191
- _pan(query, from, to, gesture_options)
183
+ _pan(query, from, to, options)
192
184
  end
193
185
 
194
186
  # Performs a `pan` between two elements.
195
187
  # @see Calabash::Gestures#pan_between
196
188
  # @!visibility private
197
189
  def pan_between(query_from, query_to, options={})
198
- Query.ensure_valid_query(query_from)
199
- Query.ensure_valid_query(query_to)
200
-
201
- gesture_options = options.dup
202
- gesture_options[:duration] ||= 1
203
- gesture_options[:timeout] ||= Calabash::Gestures::DEFAULT_GESTURE_WAIT_TIMEOUT
204
-
205
- _pan_between(query_from, query_to, gesture_options)
190
+ _pan_between(query_from, query_to, options)
206
191
  end
207
192
 
208
193
  # Performs a `flick` on the (first) view that matches `query`.
@@ -239,7 +224,7 @@ module Calabash
239
224
  # Enter `text` into the currently focused view.
240
225
  # @see Calabash::Text#enter_text
241
226
  # @!visibility private
242
- def enter_text(text)
227
+ def enter_text(text, options={})
243
228
  abstract_method!
244
229
  end
245
230
 
@@ -1,8 +1,6 @@
1
1
  module Calabash
2
2
  # Methods for performing gestures. Gestures are taps, flicks, and pans.
3
- #
4
- # Many gestures take an optional :duration. On iOS, the duration must be
5
- # between 0.5 and 60 (seconds). This is a limitation of the UIAutomation API.
3
+ # All gestures execute "physical gestures" like human users would.
6
4
  #
7
5
  # @note All gestures have _undefined return values._ This is intentional.
8
6
  # Please do not rely on return values of gestures in your tests. For
@@ -31,23 +29,24 @@ module Calabash
31
29
  # | │ 4 │
32
30
  # ┴ └─────────────────────────────────────┘
33
31
  #
34
- # 1. tap("* marked:'email'")
35
- # 2. tap("* marked:'email'", at: {x: 0, y: 0})
36
- # 3. tap("* marked:'email'", at: {x: 100, y: 0})
37
- # 4. tap("* marked:'email'", at: {x: 50, y: 100})
32
+ # 1. cal.tap("* marked:'email'")
33
+ # 2. cal.tap("* marked:'email'", at: {x: 0, y: 0})
34
+ # 3. cal.tap("* marked:'email'", at: {x: 100, y: 0})
35
+ # 4. cal.tap("* marked:'email'", at: {x: 50, y: 100})
38
36
  #
39
37
  # @param [String, Hash, Calabash::Query] query A query describing the view
40
38
  # to tap.
41
- # @param [Hash] options Options for modifying the details of the touch.
42
- # @option options [Hash] :at ({x: 50, y: 50}) The point at which the
39
+ # @param [Hash] at (default: `{x: 50, y: 50}`) The point at which the
43
40
  # gesture originates from. It is a percentage-based translation using
44
- # top-left `(0,0)` as the reference point.
41
+ # top-left `{x: 0, y: 0}` as the reference point.
45
42
  # @raise [ViewNotFoundError] If the `query` returns no results.
46
43
  # @raise [ArgumentError] If `query` is invalid.
47
- def tap(query, options={})
44
+ def tap(query, at: nil)
48
45
  Query.ensure_valid_query(query)
49
46
 
50
- Device.default.tap(Query.new(query), options)
47
+ options = {at: at || {x: 50, y: 50}}
48
+
49
+ Calabash::Internal.with_default_device {|device| device.tap(Query.new(query), options)}
51
50
  end
52
51
 
53
52
  # Performs a **double_tap** on the first view that matches `query`.
@@ -56,17 +55,18 @@ module Calabash
56
55
  #
57
56
  # @param [String, Hash, Calabash::Query] query A query describing the view
58
57
  # to tap.
59
- # @param [Hash] options Options for modifying the details of the touch.
60
- # @option options [Hash] :at ({x: 50, y: 50}) The point at which the
58
+ # @param [Hash] at (default: `{x: 50, y: 50}`) The point at which the
61
59
  # gesture originates from. It is a percentage-based translation using
62
- # top-left `(0,0)` as the reference point.
60
+ # top-left `{x: 0, y: 0}` as the reference point.
63
61
  #
64
62
  # @raise [ViewNotFoundError] If the `query` returns no results.
65
63
  # @raise [ArgumentError] If `query` is invalid.
66
- def double_tap(query, options={})
64
+ def double_tap(query, at: nil)
67
65
  Query.ensure_valid_query(query)
68
66
 
69
- Device.default.double_tap(Query.new(query), options)
67
+ options = {at: at || {x: 50, y: 50}}
68
+
69
+ Calabash::Internal.with_default_device {|device| device.double_tap(Query.new(query), options)}
70
70
  end
71
71
 
72
72
  # Performs a **long_press** on the first view that matches `query`.
@@ -77,33 +77,39 @@ module Calabash
77
77
  # @see #tap
78
78
  #
79
79
  # @param [String] query A query describing the view to tap.
80
- # @param [Hash] options Options for modifying the details of the touch.
81
- # @option options [Number] :duration (1.0) The amount of time in seconds to
80
+ # @param [Number] duration (default: 1.0) The amount of time in seconds to
82
81
  # press. On iOS, the duration must be between 0.5 and 60.
82
+ # @param [Hash] at (default: `{x: 50, y: 50}`) The point at which the
83
+ # gesture originates from. It is a percentage-based translation using
84
+ # top-left `{x: 0, y: 0}` as the reference point.
83
85
  # @raise [ViewNotFoundError] If the `query` returns no results.
84
86
  # @raise [ArgumentError] If `query` is invalid.
85
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
86
- def long_press(query, options={})
87
+ def long_press(query, duration: nil, at: nil)
87
88
  Query.ensure_valid_query(query)
88
89
 
89
- Device.default.long_press(Query.new(query), options)
90
+ options = {
91
+ at: at || {x: 50, y: 50},
92
+ duration: duration || 1.0
93
+ }
94
+
95
+ Calabash::Internal.with_default_device {|device| device.long_press(Query.new(query), options)}
90
96
  end
91
97
 
92
- # Performs a **pan** on the first view that matches `query`.
98
+ # Performs a **pan** inside the first view that matches `query`.
93
99
  #
94
100
  # A pan is a straight line swipe that pauses at the final point
95
101
  # before releasing the gesture. This is the general purpose pan method. For
96
- # standardized pans see `pan_left`, `pan_right`, `pan_up`, and `pan_down`.
97
- #
98
- # Also known as **scroll** and **swipe**.
102
+ # standardized pans see {pan_left}, {pan_right}, {pan_up}, and {pan_down}.
99
103
  #
100
104
  # @example
101
- # Consider a pan on a scrollable view. When the finger is is released,
102
- # the velocity of the view is zero.
105
+ # # Consider a pan on a scrollable view. When the finger is is released,
106
+ # # the velocity of the view is zero.
103
107
  #
104
108
  # @example
105
- # A scrollable view displays the alphabet. Panning left will cause the
106
- # view to scroll right.
109
+ # # A scrollable view displays the alphabet. Panning left will cause the
110
+ # # view to scroll right.
111
+ #
112
+ # cal.pan("* id:'alphabetView'", cal.pct(80, 80), cal.pct(20, 80))
107
113
  #
108
114
  # Before After
109
115
  # ┌───────────┐ | ┌───────────┐
@@ -112,15 +118,6 @@ module Calabash
112
118
  # │ <───────┤ │ | │ │
113
119
  # └───────────┘ | └───────────┘
114
120
  #
115
- # Apple's UIAutomation 'dragInsideWithOptions' is broken on iOS Simulators.
116
- # Call `pan` on iOS Simulators >= iOS 7.0 will raise an error. See the
117
- # iOS Scroll API for alternatives.
118
- #
119
- # @see Calabash::IOS::Scroll#scroll
120
- # @see Calabash::IOS::Scroll#scroll_to_row
121
- # @see Calabash::IOS::Scroll#scroll_to_row_with_mark
122
- # @see Calabash::IOS::Scroll#scroll_to_item
123
- # @see Calabash::IOS::Scroll#scroll_to_item_with_mark
124
121
  #
125
122
  # @param [String, Hash, Calabash::Query] query A query describing the view
126
123
  # to pan inside.
@@ -128,19 +125,18 @@ module Calabash
128
125
  # originates from.
129
126
  # @param [Hash] to `({:x, :y})` The point at which the gesture
130
127
  # ends.
131
- #
132
- # @param [Hash] options Options for modifying the details of the pan.
133
- # @option options [Number] :duration (0.5) How many seconds the pan takes
134
- # to complete. On iOS, the duration must be between 0.5 and 60.
135
- #
128
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
129
+ # gesture lasts.
136
130
  # @raise [ViewNotFoundError] If the `query` returns no results.
137
131
  # @raise [ArgumentError] If `query` is invalid.
138
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
139
- # @raise [RuntimeError] If called on an iOS Simulator > iOS 7.
140
- def pan(query, from, to, options={})
132
+ def pan(query, from, to, duration: nil)
141
133
  Query.ensure_valid_query(query)
142
134
 
143
- Device.default.pan(Query.new(query), from, to, options)
135
+ options = {
136
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
137
+ }
138
+
139
+ Calabash::Internal.with_default_device {|device| device.pan(Query.new(query), from, to, options)}
144
140
  end
145
141
 
146
142
  # Performs a **pan** from the center of the first view that matches
@@ -149,8 +145,8 @@ module Calabash
149
145
  # Also known as **drag and drop**.
150
146
  #
151
147
  # @example
152
- # Panning between two elements.
153
- # `pan_between("* id:'first'", "* id:'second'")`
148
+ # #Panning between two elements.
149
+ # cal.pan_between("* id:'first'", "* id:'second'")
154
150
  #
155
151
  #
156
152
  # ┌───────────┐
@@ -170,86 +166,137 @@ module Calabash
170
166
  # │ │
171
167
  # └───────────┘
172
168
  #
173
- # @option options [Number] :duration (1.0) How many seconds the swipe takes
174
- # to complete.
169
+ # @param [String, Hash, Calabash::Query] query_from A query describing the
170
+ # view to pan *from*
171
+ # @param [String, Hash, Calabash::Query] query_to A query describing the
172
+ # view to pan *to*
173
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
174
+ # gesture lasts.
175
175
  # @raise [ViewNotFoundError] If the `query_from` returns no results.
176
176
  # @raise [ViewNotFoundError] If the `query_to` returns no results.
177
177
  # @raise [ArgumentError] If `query_from` is invalid.
178
178
  # @raise [ArgumentError] If `query_to` is invalid.
179
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
180
- def pan_between(query_from, query_to, options={})
179
+ def pan_between(query_from, query_to, duration: nil)
181
180
  Query.ensure_valid_query(query_from)
182
181
  Query.ensure_valid_query(query_to)
183
182
 
184
- Device.default.pan_between(Query.new(query_from), Query.new(query_to), options)
183
+ options = {
184
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
185
+ }
186
+
187
+ Calabash::Internal.with_default_device do |device|
188
+ device.pan_between(Query.new(query_from), Query.new(query_to), options)
189
+ end
185
190
  end
186
191
 
187
- # Performs a **pan** heading _left_ on the first view that matches `query`.
192
+ # Performs a **pan** heading _left_ inside the first view that matches
193
+ # `query`.
188
194
  #
189
195
  # @see #pan
190
- def pan_left(query, options={})
191
- pan(query, {x: 90, y: 50}, {x: 10, y: 50}, options)
196
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
197
+ # gesture lasts.
198
+ def pan_left(query, duration: nil)
199
+ pan(query, {x: 90, y: 50}, {x: 10, y: 50}, duration: duration)
192
200
  end
193
201
 
194
- # Performs a **pan** heading _right_ on the first view that matches `query`.
202
+ # Performs a **pan** heading _right_ inside the first view that matches
203
+ # `query`.
195
204
  #
196
205
  # @see #pan
197
- def pan_right(query, options={})
198
- pan(query, {x: 10, y: 50}, {x: 90, y: 50}, options)
206
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
207
+ # gesture lasts.
208
+ def pan_right(query, duration: nil)
209
+ pan(query, {x: 10, y: 50}, {x: 90, y: 50}, duration: duration)
199
210
  end
200
211
 
201
- # Performs a **pan** heading _up_ on the first view that matches `query`.
212
+ # Performs a **pan** heading _up_ inside the first view that matches
213
+ # `query`.
202
214
  #
203
215
  # @see #pan
204
- def pan_up(query, options={})
205
- pan(query, {x: 50, y: 90}, {x: 50, y: 10}, options)
216
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
217
+ # gesture lasts.
218
+ def pan_up(query, duration: nil)
219
+ pan(query, {x: 50, y: 90}, {x: 50, y: 10}, duration: duration)
206
220
  end
207
221
 
208
- # Performs a **pan** heading _down_ on the first view that matches `query`.
222
+ # Performs a **pan** heading _down_ inside the first view that matches
223
+ # `query`.
209
224
  #
210
225
  # @see #pan
211
- def pan_down(query, options={})
212
- pan(query, {x: 50, y: 10}, {x: 50, y: 90}, options)
226
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
227
+ # gesture lasts.
228
+ def pan_down(query, duration: nil)
229
+ pan(query, {x: 50, y: 10}, {x: 50, y: 90}, duration: duration)
213
230
  end
214
231
 
215
232
  # Performs a **pan** heading _left_ on the screen.
216
233
  #
217
234
  # @see #pan
218
- def pan_screen_left(options={})
235
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
236
+ # gesture lasts.
237
+ def pan_screen_left(duration: nil)
238
+ options = {
239
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
240
+ }
241
+
219
242
  pan_left('*', options)
220
243
  end
221
244
 
222
245
  # Performs a **pan** heading _right_ on the screen.
223
246
  #
224
247
  # @see #pan
225
- def pan_screen_right(options={})
248
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
249
+ # gesture lasts.
250
+ def pan_screen_right(duration: nil)
251
+ options = {
252
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
253
+ }
254
+
226
255
  pan_right('*', options)
227
256
  end
228
257
 
229
258
  # Performs a **pan** heading _up_ on the screen.
230
259
  #
231
260
  # @see #pan
232
- def pan_screen_up(options={})
261
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
262
+ # gesture lasts.
263
+ def pan_screen_up(duration: nil)
264
+ options = {
265
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
266
+ }
267
+
233
268
  _pan_screen_up(options)
234
269
  end
235
270
 
236
271
  # Performs a **pan** heading _down_ on the screen.
237
272
  #
238
273
  # @see #pan
239
- def pan_screen_down(options={})
274
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
275
+ # gesture lasts.
276
+ def pan_screen_down(duration: nil)
277
+ options = {
278
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
279
+ }
280
+
240
281
  _pan_screen_down(options)
241
282
  end
242
283
 
243
- # Performs a **flick** on the first view that matches `query`.
284
+ # Performs a **flick** inside the first view that matches `query`.
244
285
  #
245
286
  # A flick is a straight line swipe that **lifts the finger while
246
287
  # the gesture is still in motion**. This will often cause scrollable
247
288
  # views to continue moving for some time after the gesture is released.
289
+ #
290
+ # It is likely that the gesture you want to automate is a {pan}, not a
291
+ # flick.
292
+ #
248
293
  # @see pan
249
294
  #
250
295
  # @example
251
- # A scrollable view displays the alphabet. Flicking left will cause the
252
- # view to scroll right.
296
+ # # A scrollable view displays the alphabet. Flicking left will cause the
297
+ # # view to scroll right.
298
+ #
299
+ # cal.flick("* id:'alphabetView'", cal.pct(80, 80), cal.pct(20, 80))
253
300
  #
254
301
  # Before After
255
302
  # ┌───────────┐ | ┌───────────┐
@@ -259,219 +306,266 @@ module Calabash
259
306
  # └───────────┘ | └───────────┘
260
307
  #
261
308
  # @param [String,Hash,Query] query A query describing the view to flick
262
- # inside of.
309
+ # inside.
263
310
  # @param [Hash] from `({:x, :y})` The point at which the gesture
264
311
  # originates from.
265
312
  # @param [Hash] to `({:x, :y})` The point at which the gesture
266
313
  # ends.
267
- #
268
- # @param [Hash] options Options for controlling the flick.
269
- # @option options [Numeric] :duration The duration of the flick. On iOS,
270
- # the duration must be between 0.5 and 60.
271
- #
314
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
315
+ # gesture lasts.
272
316
  # @raise [ViewNotFoundError] If the `query` returns no results.
273
317
  # @raise [ArgumentError] If `query` is invalid.
274
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
275
- def flick(query, from, to, options={})
318
+ def flick(query, from, to, duration: nil)
276
319
  Query.ensure_valid_query(query)
277
320
 
278
- Device.default.flick(Query.new(query), from, to, options)
321
+ options = {
322
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
323
+ }
324
+
325
+ Calabash::Internal.with_default_device do |device|
326
+ device.flick(Query.new(query), from, to, options)
327
+ end
279
328
  end
280
329
 
281
- # Performs a **flick** heading _left_ on the first view that matches `query`.
330
+ # Performs a **flick** heading _left_ inside the first view that matches
331
+ # `query`.
282
332
  # @see #flick
283
- def flick_left(query, options={})
284
- flick(query, {x: 90, y: 50}, {x: 10, y: 50}, options)
333
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
334
+ # gesture lasts.
335
+ def flick_left(query, duration: nil)
336
+ flick(query, {x: 90, y: 50}, {x: 10, y: 50}, duration: duration)
285
337
  end
286
338
 
287
- # Performs a **flick** heading _right_ on the first view that matches
339
+ # Performs a **flick** heading _right_ inside the first view that matches
288
340
  # `query`.
289
341
  # @see #flick
290
- def flick_right(query, options={})
291
- flick(query, {x: 10, y: 50}, {x: 90, y: 50}, options)
342
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
343
+ # gesture lasts.
344
+ def flick_right(query, duration: nil)
345
+ flick(query, {x: 10, y: 50}, {x: 90, y: 50}, duration: duration)
292
346
  end
293
347
 
294
- # Performs a **flick** heading _up_ on the first view that matches `query`.
348
+ # Performs a **flick** heading _up_ inside the first view that matches
349
+ # `query`.
295
350
  # @see #flick
296
- def flick_up(query, options={})
297
- flick(query, {x: 50, y: 90}, {x: 50, y: 10}, options)
351
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
352
+ # gesture lasts.
353
+ def flick_up(query, duration: nil)
354
+ flick(query, {x: 50, y: 90}, {x: 50, y: 10}, duration: duration)
298
355
  end
299
356
 
300
- # Performs a **flick** heading _down_ on the first view that matches `query`.
357
+ # Performs a **flick** heading _down_ inside the first view that matches
358
+ # `query`.
301
359
  # @see #flick
302
- def flick_down(query, options={})
303
- flick(query, {x: 50, y: 10}, {x: 50, y: 90}, options)
360
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
361
+ # gesture lasts.
362
+ def flick_down(query, duration: nil)
363
+ flick(query, {x: 50, y: 10}, {x: 50, y: 90}, duration: duration)
304
364
  end
305
365
 
306
366
  # Performs a **flick** heading _left_ on the screen.
307
367
  # @see #flick
308
- def flick_screen_left(options={})
368
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
369
+ # gesture lasts.
370
+ def flick_screen_left(duration: nil)
371
+ options = {
372
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
373
+ }
374
+
309
375
  flick_left('*', options)
310
376
  end
311
377
 
312
378
  # Performs a **flick** heading _right_ on the screen.
313
379
  # @see #flick
314
- def flick_screen_right(options={})
380
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
381
+ # gesture lasts.
382
+ def flick_screen_right(duration: nil)
383
+ options = {
384
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
385
+ }
386
+
315
387
  flick_right('*', options)
316
388
  end
317
389
 
318
390
  # Performs a **flick** heading _up_ on the screen.
319
391
  # @see #flick
320
- def flick_screen_up(options={})
392
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
393
+ # gesture lasts.
394
+ def flick_screen_up(duration: nil)
395
+ options = {
396
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
397
+ }
398
+
321
399
  _flick_screen_up(options)
322
400
  end
323
401
 
324
402
  # Performs a **flick** heading _down_ on the screen.
325
403
  # @see #flick
326
- def flick_screen_down(options={})
404
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
405
+ # gesture lasts.
406
+ def flick_screen_down(duration: nil)
407
+ options = {
408
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
409
+ }
410
+
327
411
  _flick_screen_down(options)
328
412
  end
329
413
 
330
- # Performs a **pinch** outwards on the first view match by `query`.
414
+ # Performs a **pinch** outwards inside the first view match by `query`.
331
415
  #
332
- # @param [String, Hash, Calabash::Query] query A query describing the view
333
- # to pinch.
334
- # @param [Hash] options Options for controlling the pinch.
335
- # @option options [Numeric] :duration The duration of the pinch. On iOS,
336
- # the duration must be between 0.5 and 60.
416
+ # The gestures will be similar to two fingers pressing down near the
417
+ # center of the view and simultaneously moving towards the opposite corners
418
+ # of the view
337
419
  #
338
- # @raise [ViewNotFoundError] If the `query` returns no results.
339
- # @raise [ArgumentError] If `query` is invalid.
340
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
341
- def pinch_out(query, options={})
342
- Device.default.pinch(:out, query, options)
343
- end
344
-
345
- # Performs a **pinch** inwards on the first view match by `query`.
420
+ # @example
421
+ # # We have a webview that we want to pinch out on
422
+ #
423
+ # cal.pinch_out("* id:'webView'")
424
+ #
425
+ # Application
426
+ # ┌───────────────────────┐
427
+ # │───────────────────────│
428
+ # │ id: webview │
429
+ # │ ┌─────────────────┐ │
430
+ # │ │ ^ │ │
431
+ # │ │ \ │ │
432
+ # │ │ \ │ │
433
+ # │ │ * * │ │
434
+ # │ │ \ │ │
435
+ # │ │ \ │ │
436
+ # │ │ v │ │
437
+ # │ └─────────────────┘ │
438
+ # └───────────────────────┘
439
+ #
440
+ # @example
441
+ # # We have a MapView rendering a map. We want to zoom it in.
442
+ # # On iOS, we should pinch out to zoom in
443
+ # # On Android, we should pinch in to zoom in.
444
+ #
445
+ # if cal.android?
446
+ # cal.pinch_in({class: "MapView"})
447
+ # elsif cal.ios?
448
+ # cal.pinch_out({class: "MapView"})
449
+ # end
346
450
  #
347
451
  # @param [String, Hash, Calabash::Query] query A query describing the view
348
452
  # to pinch.
349
- # @param [Hash] options Options for controlling the pinch.
350
- # @option options [Numeric] :duration The duration of the pinch. On iOS,
351
- # the duration must be between 0.5 and 60.
352
- #
453
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
454
+ # gesture lasts.
353
455
  # @raise [ViewNotFoundError] If the `query` returns no results.
354
456
  # @raise [ArgumentError] If `query` is invalid.
355
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
356
- def pinch_in(query, options={})
357
- Device.default.pinch(:in, query, options)
358
- end
457
+ def pinch_out(query, duration: nil)
458
+ options = {
459
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
460
+ }
359
461
 
360
- # Performs a **pinch** outwards on the screen.
361
- #
362
- # @param [Hash] options Options for controlling the pinch.
363
- # @option options [Numeric] :duration The duration of the pinch. On iOS,
364
- # the duration must be between 0.5 and 60.
365
- #
366
- # @raise [ViewNotFoundError] If the `query` returns no results.
367
- # @raise [ArgumentError] If `query` is invalid.
368
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
369
- def pinch_screen_out(options={})
370
- _pinch_screen(:out, options)
462
+ Calabash::Internal.with_default_device {|device| device.pinch(:out, query, options)}
371
463
  end
372
464
 
373
- # Performs a **pinch** inwards on the screen.
465
+ # Performs a **pinch** inwards inside the first view match by `query`.
374
466
  #
375
- # @param [Hash] options Options for controlling the pinch.
376
- # @option options [Numeric] :duration The duration of the pinch. On iOS,
377
- # the duration must be between 0.5 and 60.
467
+ # The gestures will be similar to two fingers pressing down in the opposite
468
+ # corners of the view and simultaneously moving towards the center of the
469
+ # view.
378
470
  #
379
- # @raise [ViewNotFoundError] If the `query` returns no results.
380
- # @raise [ArgumentError] If `query` is invalid.
381
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
382
- def pinch_screen_in(options={})
383
- _pinch_screen(:in, options)
384
- end
385
-
386
- # Performs a **pinch** to zoom out.
471
+ # @example
472
+ # # We have a webview that we want to pinch in on
473
+ #
474
+ # cal.pinch_in("* id:'webView'")
475
+ #
476
+ # Application
477
+ # ┌───────────────────────┐
478
+ # │───────────────────────│
479
+ # │ id: webview │
480
+ # │ ┌─────────────────┐ │
481
+ # │ │ * │ │
482
+ # │ │ \ │ │
483
+ # │ │ \ │ │
484
+ # │ │ v ^ │ │
485
+ # │ │ \ │ │
486
+ # │ │ \ │ │
487
+ # │ │ * │ │
488
+ # │ └─────────────────┘ │
489
+ # └───────────────────────┘
387
490
  #
388
- # @param [String, Hash, Calabash::Query] query A query describing the view
389
- # to pinch.
390
- # @param [Hash] options Options for controlling the pinch.
391
- # @option options [Numeric] :duration The duration of the pinch. On iOS,
392
- # the duration must be between 0.5 and 60.
491
+ # @example
492
+ # # We have a MapView rendering a map. We want to zoom it in.
493
+ # # On iOS, we should pinch out to zoom in
494
+ # # On Android, we should pinch in to zoom in.
393
495
  #
394
- # @raise [ViewNotFoundError] If the `query` returns no results.
395
- # @raise [ArgumentError] If `query` is invalid.
396
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
397
- def pinch_to_zoom_out(query, options={})
398
- _pinch_to_zoom(:out, query, options)
399
- end
400
-
401
- # Performs a **pinch** to zoom in.
496
+ # if cal.android?
497
+ # cal.pinch_in({class: "MapView"})
498
+ # elsif cal.ios?
499
+ # cal.pinch_out({class: "MapView"})
500
+ # end
402
501
  #
403
502
  # @param [String, Hash, Calabash::Query] query A query describing the view
404
503
  # to pinch.
405
- # @param [Hash] options Options for controlling the pinch.
406
- # @option options [Numeric] :duration The duration of the pinch. On iOS,
407
- # the duration must be between 0.5 and 60.
408
- #
504
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
505
+ # gesture lasts.
409
506
  # @raise [ViewNotFoundError] If the `query` returns no results.
410
507
  # @raise [ArgumentError] If `query` is invalid.
411
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
412
- def pinch_to_zoom_in(query, options={})
413
- _pinch_to_zoom(:in, query, options)
508
+ def pinch_in(query, duration: nil)
509
+ options = {
510
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
511
+ }
512
+
513
+ Calabash::Internal.with_default_device {|device| device.pinch(:in, query, options)}
414
514
  end
415
515
 
416
- # Performs a **pinch** on the screen to zoom in.
516
+ # Performs a **pinch** outwards on the screen.
417
517
  #
418
- # @param [Hash] options Options for controlling the pinch.
419
- # @option options [Numeric] :duration The duration of the pinch. On iOS,
420
- # the duration must be between 0.5 and 60.
518
+ # @see #pinch_out
421
519
  #
520
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
521
+ # gesture lasts.
422
522
  # @raise [ViewNotFoundError] If the `query` returns no results.
423
523
  # @raise [ArgumentError] If `query` is invalid.
424
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
425
- def pinch_screen_to_zoom_in(options={})
426
- _pinch_screen_to_zoom(:in, options)
524
+ def pinch_screen_out(duration: nil)
525
+ options = {
526
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
527
+ }
528
+
529
+ _pinch_screen(:out, options)
427
530
  end
428
531
 
429
- # Performs a **pinch** on the screen to zoom out.
532
+ # Performs a **pinch** inwards on the screen.
430
533
  #
431
- # @param [Hash] options Options for controlling the pinch.
432
- # @option options [Numeric] :duration The duration of the pinch. On iOS,
433
- # the duration must be between 0.5 and 60.
534
+ # @see #pinch_in
434
535
  #
536
+ # @param [Number] duration (default: 1.0) The amount of time in seconds the
537
+ # gesture lasts.
435
538
  # @raise [ViewNotFoundError] If the `query` returns no results.
436
539
  # @raise [ArgumentError] If `query` is invalid.
437
- # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
438
- def pinch_screen_to_zoom_out(options={})
439
- _pinch_screen_to_zoom(:out, options)
440
- end
540
+ def pinch_screen_in(duration: nil)
541
+ options = {
542
+ duration: duration || DEFAULT_PAN_OPTIONS[:duration]
543
+ }
441
544
 
442
- # @!visibility private
443
- def _pan_screen_up(options={})
444
- abstract_method!
445
- end
446
-
447
- # @!visibility private
448
- def _pan_screen_down(options={})
449
- abstract_method!
545
+ _pinch_screen(:in, options)
450
546
  end
451
547
 
452
548
  # @!visibility private
453
- def _flick_screen_up(options={})
454
- abstract_method!
549
+ define_method(:_pan_screen_up) do |options={}|
550
+ abstract_method!(:_pan_screen_up)
455
551
  end
456
552
 
457
553
  # @!visibility private
458
- def _flick_screen_down(options={})
459
- abstract_method!
554
+ define_method(:_pan_screen_down) do |options={}|
555
+ abstract_method!(:_pan_screen_down)
460
556
  end
461
557
 
462
558
  # @!visibility private
463
- def _pinch_screen(direction, options={})
464
- abstract_method!
559
+ define_method(:_flick_screen_up) do |options={}|
560
+ abstract_method!(:_flick_screen_up)
465
561
  end
466
562
 
467
563
  # @!visibility private
468
- def _pinch_to_zoom(direction, query, options={})
469
- abstract_method!
564
+ define_method(:_flick_screen_down) do |options={}|
565
+ abstract_method!(:_flick_screen_down)
470
566
  end
471
567
 
472
568
  # @!visibility private
473
- def _pinch_screen_to_zoom(direction, options={})
474
- abstract_method!
475
- end
569
+ DEFAULT_PAN_OPTIONS = {duration: 1}
476
570
  end
477
571
  end