calabash 1.2.1 → 1.9.9.pre1

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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +39 -0
  3. data/LICENSE +204 -21
  4. data/README.md +36 -6
  5. data/VERSIONING.md +16 -0
  6. data/bin/calabash +95 -0
  7. data/lib/calabash.rb +185 -1
  8. data/lib/calabash/android.rb +64 -0
  9. data/lib/calabash/android/adb.rb +277 -0
  10. data/lib/calabash/android/application.rb +110 -0
  11. data/lib/calabash/android/build.rb +12 -0
  12. data/lib/calabash/android/build/application.rb +13 -0
  13. data/lib/calabash/android/build/build_error.rb +11 -0
  14. data/lib/calabash/android/build/builder.rb +119 -0
  15. data/lib/calabash/android/build/java_keystore.rb +177 -0
  16. data/lib/calabash/android/build/resigner.rb +56 -0
  17. data/lib/calabash/android/build/test_server.rb +27 -0
  18. data/lib/calabash/android/console_helpers.rb +44 -0
  19. data/lib/calabash/android/cucumber.rb +3 -0
  20. data/lib/calabash/android/device.rb +965 -0
  21. data/lib/calabash/android/environment.rb +470 -0
  22. data/lib/calabash/android/gestures.rb +369 -0
  23. data/lib/calabash/android/interactions.rb +45 -0
  24. data/lib/calabash/android/lib/.irbrc +55 -0
  25. data/lib/calabash/android/lib/AndroidManifest.xml +51 -0
  26. data/lib/calabash/android/lib/TestServer.apk +0 -0
  27. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5 +0 -0
  28. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5-pie +0 -0
  29. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5 +0 -0
  30. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5-pie +0 -0
  31. data/lib/calabash/android/lib/calmd5/armeabi/calmd5 +0 -0
  32. data/lib/calabash/android/lib/calmd5/armeabi/calmd5-pie +0 -0
  33. data/lib/calabash/android/lib/calmd5/mips/calmd5 +0 -0
  34. data/lib/calabash/android/lib/calmd5/mips/calmd5-pie +0 -0
  35. data/lib/calabash/android/lib/calmd5/mips64/calmd5 +0 -0
  36. data/lib/calabash/android/lib/calmd5/mips64/calmd5-pie +0 -0
  37. data/lib/calabash/android/lib/calmd5/x86/calmd5 +0 -0
  38. data/lib/calabash/android/lib/calmd5/x86/calmd5-pie +0 -0
  39. data/lib/calabash/android/lib/calmd5/x86_64/calmd5 +0 -0
  40. data/lib/calabash/android/lib/calmd5/x86_64/calmd5-pie +0 -0
  41. data/lib/calabash/android/lib/screenshot_taker.jar +0 -0
  42. data/lib/calabash/android/life_cycle.rb +37 -0
  43. data/lib/calabash/android/orientation.rb +30 -0
  44. data/lib/calabash/android/physical_buttons.rb +39 -0
  45. data/lib/calabash/android/screenshot.rb +9 -0
  46. data/lib/calabash/android/scroll.rb +5 -0
  47. data/lib/calabash/android/server.rb +10 -0
  48. data/lib/calabash/android/text.rb +54 -0
  49. data/lib/calabash/application.rb +74 -0
  50. data/lib/calabash/cli.rb +12 -0
  51. data/lib/calabash/cli/build.rb +33 -0
  52. data/lib/calabash/cli/console.rb +90 -0
  53. data/lib/calabash/cli/generate.rb +110 -0
  54. data/lib/calabash/cli/helpers.rb +130 -0
  55. data/lib/calabash/cli/resign.rb +33 -0
  56. data/lib/calabash/cli/run.rb +99 -0
  57. data/lib/calabash/cli/setup_keystore.rb +39 -0
  58. data/lib/calabash/color.rb +32 -0
  59. data/lib/calabash/console_helpers.rb +90 -0
  60. data/lib/calabash/defaults.rb +56 -0
  61. data/lib/calabash/device.rb +401 -0
  62. data/lib/calabash/environment.rb +75 -0
  63. data/lib/calabash/gestures.rb +384 -0
  64. data/lib/calabash/http.rb +8 -0
  65. data/lib/calabash/http/error.rb +15 -0
  66. data/lib/calabash/http/request.rb +42 -0
  67. data/lib/calabash/http/retriable_client.rb +156 -0
  68. data/lib/calabash/interactions.rb +105 -0
  69. data/lib/calabash/ios.rb +37 -0
  70. data/lib/calabash/ios/application.rb +119 -0
  71. data/lib/calabash/ios/conditions.rb +79 -0
  72. data/lib/calabash/ios/console_helpers.rb +72 -0
  73. data/lib/calabash/ios/device.rb +24 -0
  74. data/lib/calabash/ios/device/device_implementation.rb +779 -0
  75. data/lib/calabash/ios/device/gestures_mixin.rb +167 -0
  76. data/lib/calabash/ios/device/keyboard_mixin.rb +133 -0
  77. data/lib/calabash/ios/device/physical_device_mixin.rb +266 -0
  78. data/lib/calabash/ios/device/rotation_mixin.rb +124 -0
  79. data/lib/calabash/ios/device/routes/backdoor_route_mixin.rb +86 -0
  80. data/lib/calabash/ios/device/routes/condition_route_mixin.rb +62 -0
  81. data/lib/calabash/ios/device/routes/error.rb +8 -0
  82. data/lib/calabash/ios/device/routes/handle_route_mixin.rb +102 -0
  83. data/lib/calabash/ios/device/routes/map_route_mixin.rb +38 -0
  84. data/lib/calabash/ios/device/routes/playback_route_mixin.rb +70 -0
  85. data/lib/calabash/ios/device/routes/response_parser.rb +48 -0
  86. data/lib/calabash/ios/device/routes/uia_route_mixin.rb +238 -0
  87. data/lib/calabash/ios/device/runtime_attributes.rb +184 -0
  88. data/lib/calabash/ios/device/status_bar_mixin.rb +17 -0
  89. data/lib/calabash/ios/device/text_mixin.rb +19 -0
  90. data/lib/calabash/ios/device/uia_keyboard_mixin.rb +188 -0
  91. data/lib/calabash/ios/device/uia_mixin.rb +12 -0
  92. data/lib/calabash/ios/environment.rb +41 -0
  93. data/lib/calabash/ios/interactions.rb +10 -0
  94. data/lib/calabash/ios/lib/.irbrc +55 -0
  95. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_ipad.base64 +2 -0
  96. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_iphone.base64 +2 -0
  97. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_ipad.base64 +2 -0
  98. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_iphone.base64 +2 -0
  99. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_ipad.base64 +2 -0
  100. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_iphone.base64 +2 -0
  101. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_ipad.base64 +2 -0
  102. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_iphone.base64 +2 -0
  103. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_ipad.base64 +2 -0
  104. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_iphone.base64 +2 -0
  105. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_ipad.base64 +2 -0
  106. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_iphone.base64 +2 -0
  107. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_ipad.base64 +2 -0
  108. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_iphone.base64 +2 -0
  109. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_ipad.base64 +2 -0
  110. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_iphone.base64 +2 -0
  111. data/lib/calabash/ios/orientation.rb +117 -0
  112. data/lib/calabash/ios/scroll.rb +504 -0
  113. data/lib/calabash/ios/server.rb +73 -0
  114. data/lib/calabash/ios/text.rb +248 -0
  115. data/lib/calabash/ios/uia.rb +24 -0
  116. data/lib/calabash/lib/skeleton/config/cucumber.yml +6 -0
  117. data/lib/calabash/lib/skeleton/features/sample.feature +5 -0
  118. data/lib/calabash/lib/skeleton/features/step_definitions/calabash_steps.rb +29 -0
  119. data/lib/calabash/lib/skeleton/features/support/env.rb +54 -0
  120. data/lib/calabash/lib/skeleton/features/support/hooks.rb +83 -0
  121. data/lib/calabash/life_cycle.rb +111 -0
  122. data/lib/calabash/location.rb +51 -0
  123. data/lib/calabash/logger.rb +87 -0
  124. data/lib/calabash/orientation.rb +84 -0
  125. data/lib/calabash/page.rb +35 -0
  126. data/lib/calabash/patch.rb +14 -0
  127. data/lib/calabash/patch/array.rb +16 -0
  128. data/lib/calabash/patch/run_loop.rb +90 -0
  129. data/lib/calabash/query.rb +160 -0
  130. data/lib/calabash/query_result.rb +85 -0
  131. data/lib/calabash/screenshot.rb +89 -0
  132. data/lib/calabash/server.rb +16 -0
  133. data/lib/calabash/text.rb +76 -0
  134. data/lib/calabash/utility.rb +58 -0
  135. data/lib/calabash/version.rb +3 -1
  136. data/lib/calabash/wait.rb +474 -0
  137. metadata +462 -24
@@ -0,0 +1,75 @@
1
+ module Calabash
2
+
3
+ # A representation of the Calabash environment.
4
+ # @todo Need ENVIRONMENT.md file.
5
+ class Environment
6
+ # Utility method to retrieve an environment variable.
7
+ #
8
+ # @param [String] name of the environment variable
9
+ # @return Value of the environment variable
10
+ def self.variable(name)
11
+ ENV[name]
12
+ end
13
+
14
+ # Utility method to set the value of an environment variable.
15
+ #
16
+ # @param [String] name of the environment variable
17
+ # @param [Object] value of the environment variable
18
+ def self.set_variable!(name, value)
19
+ Logger.debug("Setting environment variable '#{name}' to '#{value}'")
20
+ ENV[name] = value
21
+ end
22
+
23
+ # Are we running in the Xamarin Test Cloud?
24
+ #
25
+ # @return [Boolean] Returns true if cucumber is running in the test cloud.
26
+ def self.xamarin_test_cloud?
27
+ variable('XAMARIN_TEST_CLOUD') == '1'
28
+ end
29
+
30
+ # Is Calabash running in debug mode. True if $CAL_DEBUG is '1'
31
+ DEBUG = variable('CAL_DEBUG') == '1'
32
+
33
+ # The path of the default app under test. This value is used if no app is
34
+ # given from the command line. e.g. $ calabash run.
35
+ #
36
+ # @todo On iOS, a great deal of effort is spent trying to deduce the
37
+ # application path for simulators. This needs to be reproduced here
38
+ # (somehow). Or maybe not? The console requires the app path to perform
39
+ # commands. Maybe cucumber should too? See the todo in the
40
+ # Calabash::IOS::Application for more details.
41
+ APP_PATH = variable('CAL_APP')
42
+
43
+ # The time in seconds to wait by default before failing in the methods of
44
+ # {Calabash::Wait}. Defaults to 30. Notice that this value is only the
45
+ # **default** for {Calabash::Wait} and that the actual default wait timeout
46
+ # can be changed at any time during the test.
47
+ WAIT_TIMEOUT = (variable('CAL_WAIT_TIMEOUT') &&
48
+ variable('CAL_WAIT_TIMEOUT').to_i) || 15
49
+
50
+ # The directory to save screenshots in. The directory can be absolute or
51
+ # relative. Defaults to 'screenshots'.
52
+ SCREENSHOT_DIRECTORY = variable('CAL_SCREENSHOT_DIR') || 'screenshots'
53
+
54
+ # The irbrc file to load when starting a console
55
+ IRBRC = (variable('CAL_IRBRC') || (File.exist?('.irbrc') && File.expand_path('.irbrc')) || nil)
56
+
57
+ # The Android test server path
58
+ TEST_SERVER_PATH = variable('CAL_TEST_SERVER')
59
+
60
+ # The default device identifier.
61
+ #
62
+ # To change this value, set the `CAL_DEVICE_ID` environment variable.
63
+ #
64
+ # On iOS, this value can be any of the following:
65
+ # * "iPhone 5s (8.3 Simulator)"
66
+ # * "EE598265-CAB4-4F6A-96B1-3FA11693325B" # A simulator UDID.
67
+ # * 893688959205dc7eb47d603c558ede919ad8dd0f # A physical device UDID.
68
+ # * "Tom's iPhone" or "saturn" # The name of a physical device.
69
+ # * my-special-simulator # The name of a configured simulator.
70
+ DEVICE_IDENTIFIER = variable('CAL_DEVICE_ID')
71
+
72
+ # @!visibility private
73
+ SKELETON_DIR_PATH = File.join(File.dirname(__FILE__), 'lib', 'skeleton')
74
+ end
75
+ end
@@ -0,0 +1,384 @@
1
+ module Calabash
2
+ # Methods for performing gestures. Gestures are taps, flicks,
3
+ # and pans.
4
+ #
5
+ # Many gestures take an optional :duration. On iOS, the duration must be
6
+ # between 0.5 and 60 (seconds). This is a limitation of the UIAutomation API.
7
+ module Gestures
8
+
9
+ # How long do we wait for a view to appear by default when performing a
10
+ # gesture.
11
+ DEFAULT_GESTURE_WAIT_TIMEOUT = 3
12
+
13
+ # Performs a `tap` on the (first) view that matches `query`.
14
+ #
15
+ # Taps the center of the view by default.
16
+ #
17
+ # @example
18
+ # . ├────────────── 400 px ───────────────┤
19
+ #
20
+ # ┬ ┌─────────────────────────────────────┐
21
+ # | │2 3│
22
+ # | │ 4 │
23
+ # | │ │
24
+ # 200 px │ 1 │
25
+ # | │ │
26
+ # | │ 7 5 │ 6
27
+ # | │ │
28
+ # ┴ └─────────────────────────────────────┘
29
+ #
30
+ # 1. tap("* marked:'email'")
31
+ # 2. tap("* marked:'email'", at: {x: 0, y: 0})
32
+ # 3. tap("* marked:'email'", at: {x: 100, y: 0})
33
+ # 4. tap("* marked:'email'", offset: {y: -40})
34
+ # 5. tap("* marked:'email'", offset: {x: 20, y: 40})
35
+ # 6. tap("* marked:'email'", at: {x: 100, y: 75}, offset: {x: 80})
36
+ # 7. tap("* marked:'email'", at: {x: 50, y: 100},
37
+ # offset: {x: -80, y: -40})
38
+ #
39
+ # @param [String] query A query describing the view to tap.
40
+ # @param [Hash] options Options for modifying the details of the touch.
41
+ # @option options [Hash] :at ({x: 50, y: 50}) The point at which the
42
+ # gesture originates from. It is a percentage-based translation using
43
+ # top-left `(0,0)` as the reference point. This translation is always
44
+ # applied before any `:offset`.
45
+ # @option options [Hash] :offset ({x: 0, y: 0}) Offset to touch point.
46
+ # Offset supports an `:x` and `:y` key and causes the touch to be
47
+ # offset with `(x,y)`. This offset is always applied _after_ any
48
+ # translation performed by `:at`.
49
+ # @raise [ViewNotFoundError] If the `query` returns no results.
50
+ # @raise [ArgumentError] If `query` is invalid.
51
+ def tap(query, options={})
52
+ Query.ensure_valid_query(query)
53
+
54
+ Device.default.tap(Query.new(query), options)
55
+ end
56
+
57
+ # Performs a `double_tap` on the (first) view that matches `query`.
58
+ # @see tap
59
+ # @raise [ViewNotFoundError] If the `query` returns no results.
60
+ # @raise [ArgumentError] If `query` is invalid.
61
+ def double_tap(query, options={})
62
+ Query.ensure_valid_query(query)
63
+
64
+ Device.default.double_tap(Query.new(query), options)
65
+ end
66
+
67
+ # Performs a `long_press` on the (first) view that matches `query`.
68
+ # On iOS this is often referred to as _touch-and-hold_. On Android this
69
+ # is known variously as _press_, _long-push_, _press-and-hold_, or _hold_.
70
+ #
71
+ # @see tap
72
+ #
73
+ # @param [Hash] options Options for modifying the details of the touch.
74
+ # @option options [Number] :duration (1.0) The amount of time in seconds to
75
+ # press. On iOS, the duration must be between 0.5 and 60.
76
+ # @raise [ViewNotFoundError] If the `query` returns no results.
77
+ # @raise [ArgumentError] If `query` is invalid.
78
+ # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
79
+ def long_press(query, options={})
80
+ Query.ensure_valid_query(query)
81
+
82
+ Device.default.long_press(Query.new(query), options)
83
+ end
84
+
85
+ # Performs a `pan` on the (first) view that matches `query`.
86
+ # A pan is a straight line swipe that pauses at the final point
87
+ # before releasing the gesture. This is the general purpose pan method. For
88
+ # standardized pans see `pan_left`, `pan_right`, `pan_up`, and `pan_down`.
89
+ #
90
+ # @example
91
+ # Consider a pan on a scrollable view. When the finger is is released,
92
+ # the velocity of the view is zero.
93
+ #
94
+ # @example
95
+ # A scrollable view displays the alphabet. Panning left will cause the
96
+ # view to scroll right.
97
+ #
98
+ # Before After
99
+ # ┌───────────┐ | ┌───────────┐
100
+ # │ A B C D E │ | │ E F G H I │
101
+ # │ │ | │ │
102
+ # │ <───────┤ │ | │ │
103
+ # └───────────┘ | └───────────┘
104
+ #
105
+ # Apple's UIAutomation 'dragInsideWithOptions' is broken on iOS Simulators.
106
+ # Call `pan` on iOS Simulators >= iOS 7.0 will raise an error. See the
107
+ # iOS Scroll API for alternatives.
108
+ #
109
+ # @see Calabash::IOS::Scroll#scroll
110
+ # @see Calabash::IOS::Scroll#scroll_to_row
111
+ # @see Calabash::IOS::Scroll#scroll_to_row_with_mark
112
+ # @see Calabash::IOS::Scroll#scroll_to_item
113
+ # @see Calabash::IOS::Scroll#scroll_to_item_with_mark
114
+ #
115
+ # @param [String] query A query describing the view to pan inside.
116
+ # @param [Hash] from ({:x, :y}) The point at which the gesture
117
+ # originates from.
118
+ # @param [Hash] to ({:x, :y}) The point at which the gesture
119
+ # ends.
120
+ #
121
+ # @param [Hash] options Options for modifying the details of the pan.
122
+ # @option options [Number] :duration (0.5) How many seconds the pan takes
123
+ # to complete. On iOS, the duration must be between 0.5 and 60.
124
+ #
125
+ # @raise [ViewNotFoundError] If the `query` returns no results.
126
+ # @raise [ArgumentError] If `query` is invalid.
127
+ # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
128
+ # @raise [RuntimeError] If called on an iOS Simulator > iOS 7.
129
+ def pan(query, from, to, options={})
130
+ Query.ensure_valid_query(query)
131
+
132
+ Device.default.pan(Query.new(query), from, to, options)
133
+ end
134
+
135
+ # Performs a `pan` from the center of the first view that matches
136
+ # `query_from` to the center of the first view that matches `query_to`.
137
+ #
138
+ # @example
139
+ # Panning between two elements.
140
+ # `pan_between("* id:'first'", "* id:'second'")`
141
+ #
142
+ #
143
+ # ┌───────────┐
144
+ # │ │
145
+ # │ ─ │ id: 'first'
146
+ # │ \ │
147
+ # └───────\───┘
148
+ # \
149
+ # \
150
+ # \
151
+ # \
152
+ # \
153
+ # \
154
+ # ┌───\───────┐
155
+ # │ \ │
156
+ # id: 'second' │ x │
157
+ # │ │
158
+ # └───────────┘
159
+ #
160
+ # @option options [Number] :duration (1.0) How many seconds the swipe takes
161
+ # to complete.
162
+ # @raise [ViewNotFoundError] If the `query_from` returns no results.
163
+ # @raise [ViewNotFoundError] If the `query_to` returns no results.
164
+ # @raise [ArgumentError] If `query_from` is invalid.
165
+ # @raise [ArgumentError] If `query_to` is invalid.
166
+ # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
167
+ def pan_between(query_from, query_to, options={})
168
+ Query.ensure_valid_query(query_from)
169
+ Query.ensure_valid_query(query_to)
170
+
171
+ Device.default.pan_between(Query.new(query_from), Query.new(query_to), options)
172
+ end
173
+
174
+ # Performs a `pan` heading `left` on the (first) view that matches `query`.
175
+ # @see pan
176
+ def pan_left(query, options={})
177
+ pan(query, {x: 90, y: 50}, {x: 10, y: 50}, options)
178
+ end
179
+
180
+ # Performs a `pan` heading `right` on the (first) view that matches
181
+ # `query`.
182
+ # @see pan
183
+ def pan_right(query, options={})
184
+ pan(query, {x: 10, y: 50}, {x: 90, y: 50}, options)
185
+ end
186
+
187
+ # Performs a `pan` heading `up` on the (first) view that matches `query`.
188
+ # @see pan
189
+ def pan_up(query, options={})
190
+ pan(query, {x: 50, y: 90}, {x: 50, y: 10}, options)
191
+ end
192
+
193
+ # Performs a `pan` heading `down` on the (first) view that matches `query`.
194
+ # @see pan
195
+ def pan_down(query, options={})
196
+ pan(query, {x: 50, y: 10}, {x: 50, y: 90}, options)
197
+ end
198
+
199
+ # Performs a `pan` heading `left` on the screen.
200
+ # @see pan_left
201
+ def pan_screen_left(options={})
202
+ pan_left('*', options)
203
+ end
204
+
205
+ # Performs a `pan` heading `right` on the screen.
206
+ # @see pan_right
207
+ def pan_screen_right(options={})
208
+ pan_right('*', options)
209
+ end
210
+
211
+ # Performs a `pan` heading `up` on the screen.
212
+ # @see pan_up
213
+ def pan_screen_up(options={})
214
+ _pan_screen_up(options)
215
+ end
216
+
217
+ # Performs a `pan` heading `down` on the screen.
218
+ # @see pan_down
219
+ def pan_screen_down(options={})
220
+ _pan_screen_down(options)
221
+ end
222
+
223
+ # Performs a `flick` on the (first) view that matches `query`.
224
+ # A flick is a straight line swipe that **lifts the finger while
225
+ # the gesture is still in motion**. This will often cause scrollable
226
+ # views to continue moving for some time after the gesture is released.
227
+ # @see pan
228
+ #
229
+ # @example
230
+ # A scrollable view displays the alphabet. Flicking left will cause the
231
+ # view to scroll right.
232
+ #
233
+ # Before After
234
+ # ┌───────────┐ | ┌───────────┐
235
+ # │ A B C D E │ | │F G H I J K│
236
+ # │ │ | │ │
237
+ # <·····──────┤ │ | │ │
238
+ # └───────────┘ | └───────────┘
239
+ #
240
+ # @param [String,Hash,Query] query A query describing the view to flick
241
+ # inside of.
242
+ # @param [Hash] from ({:x, :y}) The point at which the gesture
243
+ # originates from.
244
+ # @param [Hash] to ({:x, :y}) The point at which the gesture
245
+ # ends.
246
+ #
247
+ # @param [Hash] options Options for controlling the flick.
248
+ # @options options [Numeric] :duration The duration of the flick. On iOS,
249
+ # the duration must be between 0.5 and 60.
250
+ #
251
+ # @raise [ViewNotFoundError] If the `query` returns no results.
252
+ # @raise [ArgumentError] If `query` is invalid.
253
+ # @raise [ArgumentError] iOS: if the `:duration` is not between 0.5 and 60.
254
+ def flick(query, from, to, options={})
255
+ Query.ensure_valid_query(query)
256
+
257
+ Device.default.flick(Query.new(query), from, to, options)
258
+ end
259
+
260
+ # Performs a `flick` heading `left` on the (first) view that matches `query`.
261
+ # @see flick
262
+ def flick_left(query, options={})
263
+ flick(query, {x: 90, y: 50}, {x: 10, y: 50}, options)
264
+ end
265
+
266
+ # Performs a `flick` heading `right` on the (first) view that matches
267
+ # `query`.
268
+ # @see flick
269
+ def flick_right(query, options={})
270
+ flick(query, {x: 10, y: 50}, {x: 90, y: 50}, options)
271
+ end
272
+
273
+ # Performs a `flick` heading `up` on the (first) view that matches `query`.
274
+ # @see flick
275
+ def flick_up(query, options={})
276
+ flick(query, {x: 50, y: 90}, {x: 50, y: 10}, options)
277
+ end
278
+
279
+ # Performs a `flick` heading `down` on the (first) view that matches `query`.
280
+ # @see flick
281
+ def flick_down(query, options={})
282
+ flick(query, {x: 50, y: 10}, {x: 50, y: 90}, options)
283
+ end
284
+
285
+ # Performs a `flick` heading `left` on the screen.
286
+ # @see flick_left
287
+ def flick_screen_left(options={})
288
+ flick_left('*', options)
289
+ end
290
+
291
+ # Performs a `flick` heading `right` on the screen.
292
+ # @see flick_right
293
+ def flick_screen_right(options={})
294
+ flick_right('*', options)
295
+ end
296
+
297
+ # Performs a `flick` heading `up` on the screen.
298
+ # @see flick_up
299
+ def flick_screen_up(options={})
300
+ _flick_screen_up(options)
301
+ end
302
+
303
+ # Performs a `flick` heading `down` on the screen.
304
+ # @see flick_down
305
+ def flick_screen_down(options={})
306
+ _flick_screen_down(options)
307
+ end
308
+
309
+ # Performs a `pinch` outwards.
310
+ def pinch_out(query, options={})
311
+ Device.default.pinch(:out, query, options)
312
+ end
313
+
314
+ # Performs a `pinch` inwards.
315
+ def pinch_in(query, options={})
316
+ Device.default.pinch(:in, query, options)
317
+ end
318
+
319
+ # Performs a `pinch` outwards on the screen.
320
+ def pinch_screen_out(options={})
321
+ _pinch_screen(:out, options)
322
+ end
323
+
324
+ # Performs a `pinch` inwards on the screen.
325
+ def pinch_screen_in(options={})
326
+ _pinch_screen(:in, options)
327
+ end
328
+
329
+ # Performs a `pinch` to zoom out.
330
+ def pinch_to_zoom_out(query, options={})
331
+ _pinch_to_zoom(:out, query, options)
332
+ end
333
+
334
+ # Performs a `pinch` to zoom in.
335
+ def pinch_to_zoom_in(query, options={})
336
+ _pinch_to_zoom(:in, query, options)
337
+ end
338
+
339
+ # Performs a `pinch` to zoom in on the screen.
340
+ def pinch_screen_to_zoom_in(options={})
341
+ _pinch_screen_to_zoom(:in, options)
342
+ end
343
+
344
+ # Performs a `pinch` to zoom in on the screen.
345
+ def pinch_screen_to_zoom_out(options={})
346
+ _pinch_screen_to_zoom(:out, options)
347
+ end
348
+
349
+ # !@visibility private
350
+ def _pan_screen_up(options={})
351
+ abstract_method!
352
+ end
353
+
354
+ # !@visibility private
355
+ def _pan_screen_down(options={})
356
+ abstract_method!
357
+ end
358
+
359
+ # !@visibility private
360
+ def _flick_screen_up(options={})
361
+ abstract_method!
362
+ end
363
+
364
+ # !@visibility private
365
+ def _flick_screen_down(options={})
366
+ abstract_method!
367
+ end
368
+
369
+ # !@visibility private
370
+ def _pinch_screen(direction, options={})
371
+ abstract_method!
372
+ end
373
+
374
+ # !@visibility private
375
+ def _pinch_to_zoom(direction, query, options={})
376
+ abstract_method!
377
+ end
378
+
379
+ # !@visibility private
380
+ def _pinch_screen_to_zoom(direction, options={})
381
+ abstract_method!
382
+ end
383
+ end
384
+ end