calabash 2.0.0.pre10 → 2.0.0.pre11

Sign up to get free protection for your applications and to get access to all the features.
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