calabash-cucumber 0.10.0.pre1 → 0.10.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. checksums.yaml +4 -4
  2. data/features/step_definitions/calabash_steps.rb +1 -1
  3. data/lib/calabash-cucumber/actions/instruments_actions.rb +15 -4
  4. data/lib/calabash-cucumber/actions/playback_actions.rb +12 -3
  5. data/lib/calabash-cucumber/connection.rb +3 -0
  6. data/lib/calabash-cucumber/connection_helpers.rb +4 -0
  7. data/lib/calabash-cucumber/core.rb +637 -83
  8. data/lib/calabash-cucumber/date_picker.rb +148 -29
  9. data/lib/calabash-cucumber/device.rb +160 -3
  10. data/lib/calabash-cucumber/environment_helpers.rb +91 -46
  11. data/lib/calabash-cucumber/failure_helpers.rb +40 -0
  12. data/lib/calabash-cucumber/http_helpers.rb +9 -2
  13. data/lib/calabash-cucumber/ibase.rb +136 -17
  14. data/lib/calabash-cucumber/ios7_operations.rb +13 -9
  15. data/lib/calabash-cucumber/ipad_1x_2x.rb +103 -48
  16. data/lib/calabash-cucumber/keyboard_helpers.rb +253 -144
  17. data/lib/calabash-cucumber/keychain_helpers.rb +46 -32
  18. data/lib/calabash-cucumber/launch/simulator_helper.rb +13 -12
  19. data/lib/calabash-cucumber/launch/simulator_launcher.rb +111 -78
  20. data/lib/calabash-cucumber/launcher.rb +265 -25
  21. data/lib/calabash-cucumber/map.rb +24 -22
  22. data/lib/calabash-cucumber/operations.rb +4 -160
  23. data/lib/calabash-cucumber/playback_helpers.rb +26 -0
  24. data/lib/calabash-cucumber/query_helpers.rb +12 -0
  25. data/lib/calabash-cucumber/rotation_helpers.rb +64 -8
  26. data/lib/calabash-cucumber/status_bar_helpers.rb +40 -3
  27. data/lib/calabash-cucumber/tests_helpers.rb +43 -14
  28. data/lib/calabash-cucumber/uia.rb +93 -9
  29. data/lib/calabash-cucumber/utils/logging.rb +30 -16
  30. data/lib/calabash-cucumber/utils/plist_buddy.rb +18 -19
  31. data/lib/calabash-cucumber/utils/simulator_accessibility.rb +41 -30
  32. data/lib/calabash-cucumber/utils/xctools.rb +31 -21
  33. data/lib/calabash-cucumber/version.rb +98 -2
  34. data/lib/calabash-cucumber/wait_helpers.rb +257 -77
  35. data/staticlib/calabash.framework.zip +0 -0
  36. metadata +64 -231
  37. data/.gitignore +0 -17
  38. data/CHANGES.txt +0 -1
  39. data/Gemfile +0 -4
  40. data/Rakefile +0 -72
  41. data/calabash-cucumber.gemspec +0 -36
  42. data/epl-v10.html +0 -261
  43. data/lib/calabash-cucumber/resources/cell_swipe_ios4_ipad.base64 +0 -51
  44. data/lib/calabash-cucumber/resources/cell_swipe_ios4_iphone.base64 +0 -51
  45. data/lib/calabash-cucumber/resources/cell_swipe_ios5_ipad.base64 +0 -74
  46. data/lib/calabash-cucumber/resources/cell_swipe_ios5_iphone.base64 +0 -74
  47. data/lib/calabash-cucumber/resources/double_tap_ios5_ipad.base64 +0 -15
  48. data/lib/calabash-cucumber/resources/double_tap_ios5_iphone.base64 +0 -15
  49. data/lib/calabash-cucumber/resources/double_tap_ios6_ipad.base64 +0 -22
  50. data/lib/calabash-cucumber/resources/double_tap_ios6_iphone.base64 +0 -22
  51. data/lib/calabash-cucumber/resources/pan_ios5_ipad.base64 +0 -199
  52. data/lib/calabash-cucumber/resources/pan_ios5_iphone.base64 +0 -199
  53. data/lib/calabash-cucumber/resources/pan_ios6_ipad.base64 +0 -206
  54. data/lib/calabash-cucumber/resources/pan_ios6_iphone.base64 +0 -206
  55. data/lib/calabash-cucumber/resources/pinch_in_ios4_ipad.base64 +0 -104
  56. data/lib/calabash-cucumber/resources/pinch_in_ios4_iphone.base64 +0 -104
  57. data/lib/calabash-cucumber/resources/pinch_in_ios5_ipad.base64 +0 -144
  58. data/lib/calabash-cucumber/resources/pinch_in_ios5_iphone.base64 +0 -144
  59. data/lib/calabash-cucumber/resources/pinch_in_ios6_ipad.base64 +0 -70
  60. data/lib/calabash-cucumber/resources/pinch_in_ios6_iphone.base64 +0 -70
  61. data/lib/calabash-cucumber/resources/pinch_out_ios5_ipad.base64 +0 -207
  62. data/lib/calabash-cucumber/resources/pinch_out_ios5_iphone.base64 +0 -207
  63. data/lib/calabash-cucumber/resources/pinch_out_ios6_ipad.base64 +0 -96
  64. data/lib/calabash-cucumber/resources/pinch_out_ios6_iphone.base64 +0 -96
  65. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_ipad.base64 +0 -2
  66. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_iphone.base64 +0 -2
  67. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_ipad.base64 +0 -2
  68. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_iphone.base64 +0 -2
  69. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_ipad.base64 +0 -2
  70. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_iphone.base64 +0 -2
  71. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_ipad.base64 +0 -2
  72. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_iphone.base64 +0 -2
  73. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_ipad.base64 +0 -2
  74. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_iphone.base64 +0 -2
  75. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_ipad.base64 +0 -2
  76. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_iphone.base64 +0 -2
  77. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_ipad.base64 +0 -2
  78. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_iphone.base64 +0 -2
  79. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_ipad.base64 +0 -2
  80. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_iphone.base64 +0 -2
  81. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_ipad.base64 +0 -2
  82. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_iphone.base64 +0 -2
  83. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_ipad.base64 +0 -2
  84. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_iphone.base64 +0 -2
  85. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_ipad.base64 +0 -2
  86. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_iphone.base64 +0 -2
  87. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_ipad.base64 +0 -2
  88. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_iphone.base64 +0 -2
  89. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_ipad.base64 +0 -2
  90. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_iphone.base64 +0 -2
  91. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_ipad.base64 +0 -2
  92. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_iphone.base64 +0 -2
  93. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_ipad.base64 +0 -2
  94. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_iphone.base64 +0 -2
  95. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_ipad.base64 +0 -2
  96. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_iphone.base64 +0 -2
  97. data/lib/calabash-cucumber/resources/swipe_down_ios5_ipad.base64 +0 -18
  98. data/lib/calabash-cucumber/resources/swipe_down_ios5_iphone.base64 +0 -31
  99. data/lib/calabash-cucumber/resources/swipe_down_ios6_ipad.base64 +0 -25
  100. data/lib/calabash-cucumber/resources/swipe_down_ios6_iphone.base64 +0 -25
  101. data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_ipad.base64 +0 -15
  102. data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_iphone.base64 +0 -15
  103. data/lib/calabash-cucumber/resources/swipe_left_ios4_ipad.base64 +0 -18
  104. data/lib/calabash-cucumber/resources/swipe_left_ios4_iphone.base64 +0 -18
  105. data/lib/calabash-cucumber/resources/swipe_left_ios5_ipad.base64 +0 -17
  106. data/lib/calabash-cucumber/resources/swipe_left_ios5_iphone.base64 +0 -34
  107. data/lib/calabash-cucumber/resources/swipe_left_ios6_ipad.base64 +0 -28
  108. data/lib/calabash-cucumber/resources/swipe_left_ios6_iphone.base64 +0 -28
  109. data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_ipad.base64 +0 -17
  110. data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_iphone.base64 +0 -17
  111. data/lib/calabash-cucumber/resources/swipe_right_ios4_ipad.base64 +0 -13
  112. data/lib/calabash-cucumber/resources/swipe_right_ios4_iphone.base64 +0 -13
  113. data/lib/calabash-cucumber/resources/swipe_right_ios5_ipad.base64 +0 -17
  114. data/lib/calabash-cucumber/resources/swipe_right_ios5_iphone.base64 +0 -17
  115. data/lib/calabash-cucumber/resources/swipe_right_ios6_ipad.base64 +0 -25
  116. data/lib/calabash-cucumber/resources/swipe_right_ios6_iphone.base64 +0 -25
  117. data/lib/calabash-cucumber/resources/swipe_up_ios5_ipad.base64 +0 -34
  118. data/lib/calabash-cucumber/resources/swipe_up_ios5_iphone.base64 +0 -28
  119. data/lib/calabash-cucumber/resources/swipe_up_ios6_ipad.base64 +0 -25
  120. data/lib/calabash-cucumber/resources/swipe_up_ios6_iphone.base64 +0 -25
  121. data/lib/calabash-cucumber/resources/touch_done_ios4_ipad.base64 +0 -7
  122. data/lib/calabash-cucumber/resources/touch_done_ios4_iphone.base64 +0 -9
  123. data/lib/calabash-cucumber/resources/touch_done_ios5_ipad.base64 +0 -7
  124. data/lib/calabash-cucumber/resources/touch_done_ios5_iphone.base64 +0 -9
  125. data/lib/calabash-cucumber/resources/touch_hold_ios5_ipad.base64 +0 -9
  126. data/lib/calabash-cucumber/resources/touch_hold_ios5_iphone.base64 +0 -9
  127. data/lib/calabash-cucumber/resources/touch_hold_ios6_ipad.base64 +0 -9
  128. data/lib/calabash-cucumber/resources/touch_hold_ios6_iphone.base64 +0 -9
  129. data/lib/calabash-cucumber/resources/touch_ios4_ipad.base64 +0 -9
  130. data/lib/calabash-cucumber/resources/touch_ios4_iphone.base64 +0 -9
  131. data/lib/calabash-cucumber/resources/touch_ios5_ipad.base64 +0 -9
  132. data/lib/calabash-cucumber/resources/touch_ios5_iphone.base64 +0 -9
  133. data/lib/calabash-cucumber/resources/touch_ios7_ipad.base64 +0 -9
  134. data/lib/calabash-cucumber/resources/touch_ios7_iphone.base64 +0 -9
  135. data/lib/calabash-cucumber/resources/wheel_down_ios4_ipad.base64 +0 -159
  136. data/lib/calabash-cucumber/resources/wheel_down_ios4_iphone.base64 +0 -159
  137. data/lib/calabash-cucumber/resources/wheel_down_ios5_ipad.base64 +0 -156
  138. data/lib/calabash-cucumber/resources/wheel_down_ios5_iphone.base64 +0 -156
  139. data/lib/calabash-cucumber/resources/wheel_up_ios4_ipad.base64 +0 -166
  140. data/lib/calabash-cucumber/resources/wheel_up_ios4_iphone.base64 +0 -166
  141. data/lib/calabash-cucumber/resources/wheel_up_ios5_ipad.base64 +0 -156
  142. data/lib/calabash-cucumber/resources/wheel_up_ios5_iphone.base64 +0 -156
  143. data/scripts/EmptyAppHack.app/Default-568h@2x.png +0 -0
  144. data/scripts/EmptyAppHack.app/Default.png +0 -0
  145. data/scripts/EmptyAppHack.app/Default@2x.png +0 -0
  146. data/scripts/EmptyAppHack.app/EmptyAppHack +0 -0
  147. data/scripts/EmptyAppHack.app/Info.plist +0 -0
  148. data/scripts/EmptyAppHack.app/PkgInfo +0 -1
  149. data/scripts/EmptyAppHack.app/en.lproj/InfoPlist.strings +0 -0
  150. data/scripts/com.example.plist +0 -0
  151. data/scripts/data/.GlobalPreferences.plist +0 -0
  152. data/scripts/reset_simulator.scpt +0 -0
  153. data/spec/bin/calabash_ios_sim_spec.rb +0 -24
  154. data/spec/launcher_spec.rb +0 -166
  155. data/spec/logging_spec.rb +0 -38
  156. data/spec/plist_buddy_spec.rb +0 -99
  157. data/spec/resources/enable-accessibility/6.1/.gitkeep +0 -0
  158. data/spec/resources/enable-accessibility/7.0.3-64/.gitkeep +0 -0
  159. data/spec/resources/enable-accessibility/7.0.3/.gitkeep +0 -0
  160. data/spec/resources/enable-accessibility/7.1-64/.gitkeep +0 -0
  161. data/spec/resources/enable-accessibility/7.1/.gitkeep +0 -0
  162. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/Default-568h@2x.png +0 -0
  163. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/Info.plist +0 -0
  164. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/LPSimpleExample-cal +0 -0
  165. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/PkgInfo +0 -1
  166. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/InfoPlist.strings +0 -0
  167. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFirstViewController.nib +0 -0
  168. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFirstViewController~ipad.nib +0 -0
  169. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFourthViewController.nib +0 -0
  170. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFourthViewController~ipad.nib +0 -0
  171. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPSecondViewController.nib +0 -0
  172. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPSecondViewController~ipad.nib +0 -0
  173. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPThirdViewController.nib +0 -0
  174. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPThirdViewController~ipad.nib +0 -0
  175. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/first.png +0 -0
  176. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/first@2x.png +0 -0
  177. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/second.png +0 -0
  178. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/second@2x.png +0 -0
  179. data/spec/resources/plist_buddy/com.example.plist +0 -0
  180. data/spec/resources/plist_buddy/com.testing.plist +0 -18
  181. data/spec/simulator_accessibility_spec.rb +0 -206
  182. data/spec/spec_helper.rb +0 -31
  183. data/spec/version_spec.rb +0 -13
  184. data/spec/xctools_spec.rb +0 -58
@@ -9,17 +9,45 @@ require 'cfpropertylist'
9
9
  require 'calabash-cucumber/version'
10
10
  require 'calabash-cucumber/utils/logging'
11
11
 
12
-
12
+ # Used to launch apps for testing in iOS Simulator or on iOS Devices. By default
13
+ # it uses Apple's `instruments` process to launch your app, but has legacy support
14
+ # for using `sim_launcher`.
15
+ #
16
+ # ### Accessing the current launcher from ruby.
17
+ #
18
+ # If you need a reference to the current launcher in your ruby code.
19
+ # This is usually not required, but might be useful in `support/01_launch.rb`.
20
+ #
21
+ # `Calabash::Cucumber::Launcher.launcher`
22
+ #
23
+ # ### Attaching to the current launcher in a console
24
+ #
25
+ # If Calabash already running and you want to attach to the current launcher,
26
+ # use `console_attach`. This is useful when a cucumber Scenario has failed and
27
+ # you want to query the current state of the app.
28
+ #
29
+ # * **Pro Tip:** set the `NO_STOP` environmental variable to 1 so calabash does
30
+ # not exit the simulator when a Scenario fails.
13
31
  class Calabash::Cucumber::Launcher
14
32
 
15
33
  include Calabash::Cucumber::Logging
16
34
  include Calabash::Cucumber::SimulatorAccessibility
17
35
 
36
+ # A hash of known privacy settings that calabash can control.
18
37
  KNOWN_PRIVACY_SETTINGS = {:photos => 'kTCCServicePhotos', :calendar => 'kTCCServiceCalendar', :address_book => 'kTCCServiceAddressBook'}
19
38
 
39
+ # noinspection RubyClassVariableUsageInspection
40
+
41
+ # @!visibility private
20
42
  @@launcher = nil
21
43
 
44
+ # @!visibility private
22
45
  SERVER_VERSION_NOT_AVAILABLE = '0.0.0'
46
+ # noinspection RubyClassVariableUsageInspection
47
+
48
+ # @!visibility private
49
+ # Class variable for caching the embedded server version so we only need to
50
+ # check the server version one time.
23
51
  @@server_version = nil
24
52
 
25
53
  attr_accessor :run_loop
@@ -28,6 +56,8 @@ class Calabash::Cucumber::Launcher
28
56
  attr_accessor :launch_args
29
57
  attr_accessor :simulator_launcher
30
58
 
59
+ # @!visibility private
60
+ # Generated when calabash cannot launch the app.
31
61
  class StartError < RuntimeError
32
62
  attr_accessor :error
33
63
 
@@ -35,31 +65,37 @@ class Calabash::Cucumber::Launcher
35
65
  self.error= err
36
66
  end
37
67
 
68
+ # @!visibility private
38
69
  def to_s
39
70
  "#{super.to_s}: #{error}"
40
71
  end
41
72
  end
42
73
 
74
+ # @!visibility private
75
+ # Generated when calabash cannot communicate with the app.
43
76
  class CalabashLauncherTimeoutErr < Timeout::Error
44
77
  end
45
78
 
46
-
79
+ # @!visibility private
47
80
  def initialize
48
81
  @simulator_launcher = Calabash::Cucumber::SimulatorLauncher.new
49
82
  @@launcher = self
50
83
  end
51
84
 
85
+ # @!visibility private
52
86
  def actions
53
87
  attach if @actions.nil?
54
88
  @actions
55
89
  end
56
90
 
91
+ # @see Calabash::Cucumber::Core#console_attach
57
92
  def self.attach
58
93
  l = launcher
59
94
  return l if l && l.active?
60
95
  l.attach
61
96
  end
62
97
 
98
+ # @see Calabash::Cucumber::Core#console_attach
63
99
  def attach(max_retry=1, timeout=10)
64
100
  if calabash_no_launch?
65
101
  self.actions= Calabash::Cucumber::PlaybackActions.new
@@ -95,20 +131,30 @@ class Calabash::Cucumber::Launcher
95
131
  self
96
132
  end
97
133
 
134
+ # Are we running using instruments?
135
+ #
136
+ # @return {Boolean} true if we're using instruments to launch
98
137
  def self.instruments?
99
138
  l = launcher_if_used
100
139
  return false unless l
101
140
  l.instruments?
102
141
  end
103
142
 
143
+ # Get a reference to the current launcher (instantiates a new one if needed). Usually we use a singleton launcher throughout a test run.
144
+ # @return {Calabash::Cucumber::Launcher} the current launcher
104
145
  def self.launcher
105
146
  @@launcher ||= Calabash::Cucumber::Launcher.new
106
147
  end
107
148
 
149
+ # Get a reference to the current launcher (does not instantiate a new one if unset).
150
+ # Usually we use a singleton launcher throughout a test run.
151
+ # @return {Calabash::Cucumber::Launcher} the current launcher or nil
108
152
  def self.launcher_if_used
109
153
  @@launcher
110
154
  end
111
155
 
156
+ # "Major" component of the current iOS version of the device
157
+ # @return {String} the "major" component, e.g., "7" for "7.1.1"
112
158
  def ios_major_version
113
159
  # pinging the app will set self.device
114
160
  ping_app if self.device.nil?
@@ -117,36 +163,141 @@ class Calabash::Cucumber::Launcher
117
163
  device.ios_major_version
118
164
  end
119
165
 
166
+ # the current iOS version of the device
167
+ # @return {String} the current iOS version of the device
120
168
  def ios_version
121
169
  return nil if device.nil?
122
170
  device.ios_version
123
171
  end
124
172
 
173
+ # @deprecated 0.10.0 Replaced with {#reset_app_sandbox}.
174
+ # Reset the app sandbox for a device.
125
175
  def reset_app_jail(sdk=nil, path=nil)
126
- sdk ||= sdk_version || self.simulator_launcher.sdk_detector.latest_sdk_version
127
- path ||= self.simulator_launcher.app_bundle_or_raise(app_path)
176
+ # will be deprecated in a future version
177
+ #_deprecated('0.10.0', 'use reset_app_sandbox instead', :warn)
178
+ reset_app_sandbox({:sdk => sdk, :path => path})
179
+ end
180
+
181
+ # Resets the app's content and settings by deleting the following directories
182
+ # from application sandbox:
183
+ #
184
+ # * Library
185
+ # * Documents
186
+ # * tmp
187
+ #
188
+ # @note It is not recommended that you call this method directly. See the
189
+ # examples below for how use the `RESET_BETWEEN_SCENARIOS` environmental
190
+ # variable to reset the app sandbox.
191
+ #
192
+ # @note This method is only available for the iOS Simulator.
193
+ #
194
+ # @note Generates a warning if called when targeting a physical device and
195
+ # otherwise has no effect.
196
+ #
197
+ # @note When testing against the Xamarin Test Cloud, this method is never
198
+ # called. Use the `RESET_BETWEEN_SCENARIOS` environmental variable.
199
+ # See the examples.
200
+ #
201
+ # @example Use `RESET_BETWEEN_SCENARIOS` to reset the app sandbox before every Scenario.
202
+ # When testing devices outside the Xamarin Test Cloud this has no effect.
203
+ #
204
+ # On the Xamarin Test Cloud, the app sandbox will be reset, but this method
205
+ # will not be called; the resetting is done via an alternative mechanism.
206
+ #
207
+ # When testing simulators, this method will be called.
208
+ #
209
+ # Launch cucumber with RESET_BETWEEN_SCENARIOS=1
210
+ #
211
+ # $ RESET_BETWEEN_SCENARIOS=1 bundle exec cucumber
212
+ #
213
+ # @example Use tags and a Before hook to reset the app sandbox before specific Scenarios.
214
+ # # in your .feature file
215
+ #
216
+ # @reset_app_before_hook
217
+ # Scenario: some scenario that requires the app be reset
218
+ #
219
+ # # in your support/01_launch.rb file
220
+ # #
221
+ # # 1. add a Before hook
222
+ # Before('@reset_app_before_hook') do
223
+ # ENV['RESET_BETWEEN_SCENARIOS'] = '1'
224
+ # end
225
+ #
226
+ # # 2. after launching, revert the env var value
227
+ # Before do |scenario|
228
+ # # launch the app
229
+ # launcher = Calabash::Cucumber::Launcher.new
230
+ # unless launcher.calabash_no_launch?
231
+ # launcher.relaunch
232
+ # launcher.calabash_notify(self)
233
+ # end
234
+ # # disable resetting between Scenarios
235
+ # ENV['RESET_BETWEEN_SCENARIOS'] = ''
236
+ # end
237
+ #
238
+ # @param [Hash] opts can pass the target sdk or the path to the application bundle
239
+ # @option opts [String, Symbol] :sdk (nil) The target sdk. If nil is
240
+ # passed, then only app sandbox for the latest sdk will be deleted. If
241
+ # `:all` is passed, then the sandboxes for all sdks will be deleted.
242
+ # @option opts [String] :path (nil) path to the application bundle
243
+ def reset_app_sandbox(opts={})
244
+
245
+ if device_target?
246
+ calabash_warn("calling 'reset_app_sandbox' when targeting a device.")
247
+ return
248
+ end
249
+
250
+ default_opts = {:sdk => nil, :path => nil}
251
+ merged_opts = default_opts.merge opts
252
+
253
+ sdk ||= merged_opts[:sdk] || sdk_version || self.simulator_launcher.sdk_detector.latest_sdk_version
254
+ path ||= merged_opts[:path] || self.simulator_launcher.app_bundle_or_raise(app_path)
128
255
 
129
256
  app = File.basename(path)
130
- directories_for_sdk_prefix(sdk).each do |dir|
131
- bundle = `find "#{dir}/Applications" -type d -depth 2 -name "#{app}" | head -n 1`
257
+
258
+ directories_for_sdk_prefix(sdk).each do |sdk_dir|
259
+ app_dir = File.expand_path("#{sdk_dir}/Applications")
260
+ next unless File.exists?(app_dir)
261
+
262
+ bundle = `find "#{app_dir}" -type d -depth 2 -name "#{app}" | head -n 1`
263
+
132
264
  next if bundle.empty? # Assuming we're already clean
265
+
133
266
  if debug_logging?
134
267
  puts "Reset app state for #{bundle}"
135
268
  end
136
269
  sandbox = File.dirname(bundle)
137
- ['Library', 'Documents', 'tmp'].each do |dir|
138
- FileUtils.rm_rf(File.join(sandbox, dir))
270
+ ['Library', 'Documents', 'tmp'].each do |content_dir|
271
+ FileUtils.rm_rf(File.join(sandbox, content_dir))
139
272
  end
140
273
  end
274
+ end
141
275
 
142
-
276
+ # Simulates touching the iOS Simulator > Reset Content and Settings... menu
277
+ # item.
278
+ #
279
+ # @note
280
+ # **WARNING** This is a destructive operation. You have been warned.
281
+ #
282
+ # @raise RuntimeError if called when targeting a physical device
283
+ def reset_simulator
284
+ if device_target?
285
+ raise "calling 'reset_simulator' when targeting a device is not allowed"
286
+ end
287
+ reset_simulator_content_and_settings
143
288
  end
144
289
 
290
+ # @!visibility private
145
291
  def directories_for_sdk_prefix(sdk)
146
- Dir["#{ENV['HOME']}/Library/Application Support/iPhone Simulator/#{sdk}*"]
292
+ if sdk == :all
293
+ existing_simulator_support_sdk_dirs
294
+ else
295
+ Dir["#{simulator_app_support_dir}/#{sdk}*"]
296
+ end
147
297
  end
148
298
 
149
- # Call as update_privacy_settings('com.my.app', {:photos => {:allow => true}})
299
+ # Call as `update_privacy_settings('com.my.app', {:photos => {:allow => true}})`
300
+ # @!visibility private
150
301
  def update_privacy_settings(bundle_id, opts={})
151
302
  if debug_logging?
152
303
  puts "Update privacy settings #{bundle_id}, #{opts}"
@@ -191,13 +342,14 @@ class Calabash::Cucumber::Launcher
191
342
  end
192
343
  end
193
344
  end
194
-
195
345
  end
196
346
 
347
+ # @!visibility private
197
348
  def tcc_database_for_sdk_dir(dir)
198
349
  File.join(dir,'Library', 'TCC', 'TCC.db')
199
350
  end
200
351
 
352
+ # @!visibility private
201
353
  def privacy_setting(sdk_dir, bundle_id, setting_name)
202
354
  setting_name = KNOWN_PRIVACY_SETTINGS[setting_name] || setting_name
203
355
  path_to_tcc_db = tcc_database_for_sdk_dir(sdk_dir)
@@ -207,6 +359,7 @@ class Calabash::Cucumber::Launcher
207
359
  (output == '0' || output == '1') ? output.to_i : nil
208
360
  end
209
361
 
362
+ # @!visibility private
210
363
  def default_launch_args
211
364
  # APP_BUNDLE_PATH
212
365
  # BUNDLE_ID
@@ -249,11 +402,12 @@ class Calabash::Cucumber::Launcher
249
402
  end
250
403
 
251
404
  if args[:device_target].nil?
252
- args[:device_target] = 'simulator'
405
+ args[:device_target] = device_tgt || 'simulator'
253
406
  end
254
407
  args
255
408
  end
256
409
 
410
+ # @!visibility private
257
411
  def detect_connected_device?
258
412
  if ENV['DETECT_CONNECTED_DEVICE'] == '1'
259
413
  return true
@@ -272,6 +426,7 @@ class Calabash::Cucumber::Launcher
272
426
  return false
273
427
  end
274
428
 
429
+ # @!visibility private
275
430
  def default_launch_method
276
431
  sdk = sdk_version
277
432
  major = nil
@@ -298,7 +453,35 @@ class Calabash::Cucumber::Launcher
298
453
  end
299
454
  end
300
455
 
456
+ # Launches your app on the connected device or simulator. Stops the app if it is already running.
457
+ # `relaunch` does a lot of error detection and handling to reliably start the app and test. Instruments (particularly the cli)
458
+ # has stability issues which we workaround by restarting the simulator process and checking that UIAutomation is correctly
459
+ # attaching.
460
+ #
461
+ # Takes optional args to specify details of the launch (e.g. device or simulator, sdk version, target device, launch method...).
462
+ # @note an important part of relaunch behavior is controlled by environment variables, specified below
463
+ #
464
+ # The two most important environment variables are `DEVICE_TARGET` and `APP_BUNDLE_PATH`.
465
+ #
466
+ # - `DEVICE_TARGET` controls which device you're running on. To see the options run: `instruments -s devices`.
467
+ # In addition you can specify `DEVICE_TARGET=device` to run on a (unique) usb-connected device.
468
+ # - `APP_BUNDLE_PATH` controls which `.app` bundle to launch in simulator (don't use for on-device testing, instead use `BUNDLE_ID`).
469
+ # - `BUNDLE_ID` used with `DEVICE_TARGET=device` to specify which app to launch on device
470
+ # - `DEBUG` - set to "1" to obtain debug info (typically used to debug launching, UIAutomation and other issues)
471
+ # - `DEBUG_HTTP` - set to "1" to show raw HTTP traffic
472
+ #
473
+ #
474
+ # @example Launching on iPad simulator with DEBUG settings
475
+ # DEBUG_HTTP=1 DEVICE_TARGET="iPad - Simulator - iOS 7.1" DEBUG=1 APP_BUNDLE_PATH=FieldServiceiOS.app bundle exec calabash-ios console
476
+ # @param {Hash} args optional args to specify details of the launch (e.g. device or simulator, sdk version,
477
+ # target device, launch method...).
478
+ # @option args {String} :app (detect the location of the bundle from project settings) app bundle path
479
+ # @option args {String} :bundle_id if launching on device, specify this or env `BUNDLE_ID` to be the bundle identifier
480
+ # of the application to launch
481
+ # @option args {Hash} :privacy_settings preset privacy settings for the, e.g., `{:photos => {:allow => true}}`.
482
+ # See {KNOWN_PRIVACY_SETTINGS}
301
483
  def relaunch(args={})
484
+ #TODO stopping is currently broken, but this works anyway because instruments stop the process before relaunching
302
485
  RunLoop.stop(run_loop) if run_loop
303
486
 
304
487
  args = default_launch_args.merge(args)
@@ -330,9 +513,25 @@ class Calabash::Cucumber::Launcher
330
513
 
331
514
  args[:device] ||= detect_device_from_args(args)
332
515
 
333
-
334
- reset_app_jail if args[:reset]
335
-
516
+ if simulator_target?(args) and args[:reset]
517
+ # attempt to find the sdk version from the :device_target
518
+ sdk = sdk_version_for_simulator_target(args)
519
+
520
+ # *** LEGACY SUPPORT ***
521
+ # If DEVICE_TARGET has not been set and is not a device UDID, then
522
+ # :device_target will be 'simulator'. In that case, we cannot know what
523
+ # SDK version of the app sandbox we should reset. The user _might_ give
524
+ # us a hint with SDK_VERSION, but we want to deprecate that variable ASAP.
525
+ #
526
+ # If passed a nil SDK arg, reset_app_sandbox will reset the _latest_ SDK.
527
+ # This is not good, because this is probably _not_ the SDK that should be
528
+ # reset. Our only option is to reset every sandbox for all SDKs by
529
+ # passing :sdk => :all to reset_app_sandbox.
530
+ if sdk.nil? and args[:device_target] == 'simulator'
531
+ sdk = :all
532
+ end
533
+ reset_app_sandbox({:sdk => sdk, :path => args[:app]})
534
+ end
336
535
 
337
536
  if args[:privacy_settings]
338
537
  if simulator_target?(args)
@@ -361,6 +560,7 @@ class Calabash::Cucumber::Launcher
361
560
  check_server_gem_compatibility
362
561
  end
363
562
 
563
+ # @!visibility private
364
564
  def detect_device_from_args(args)
365
565
  if args[:app] && File.directory?(args[:app])
366
566
  # Derive bundle id from bundle_dir
@@ -379,11 +579,9 @@ class Calabash::Cucumber::Launcher
379
579
  else
380
580
  args[:app]
381
581
  end
382
-
383
-
384
582
  end
385
583
 
386
- # todo this method should be migrated to the Simulator Launcher
584
+ # @!visibility private
387
585
  def detect_app_bundle_from_args(args)
388
586
  if simulator_target?(args)
389
587
  device_xamarin_build_dir = 'iPhoneSimulator'
@@ -394,6 +592,7 @@ class Calabash::Cucumber::Launcher
394
592
  self.simulator_launcher.detect_app_bundle(nil, device_xamarin_build_dir)
395
593
  end
396
594
 
595
+ # @!visibility private
397
596
  def detect_bundle_id_from_app_bundle(args)
398
597
  if args[:app] && File.directory?(args[:app])
399
598
  # Derive bundle id from bundle_dir
@@ -406,11 +605,13 @@ class Calabash::Cucumber::Launcher
406
605
  end
407
606
  end
408
607
 
608
+ # @!visibility private
409
609
  def info_plist_from_bundle_path(bundle_path)
410
610
  plist_path = File.join(bundle_path, 'Info.plist')
411
611
  info_plist_as_hash(plist_path) if File.exist?(plist_path)
412
612
  end
413
613
 
614
+ # @!visibility private
414
615
  def new_run_loop(args)
415
616
 
416
617
  # for stability, quit the simulator if Xcode version is > 5.1 and the
@@ -441,6 +642,7 @@ class Calabash::Cucumber::Launcher
441
642
  raise StartError.new(last_err)
442
643
  end
443
644
 
645
+ # @!visibility private
444
646
  def ensure_connectivity(max_retry=10, timeout=30)
445
647
  begin
446
648
  max_retry_count = (ENV['MAX_CONNECT_RETRY'] || max_retry).to_i
@@ -484,6 +686,7 @@ class Calabash::Cucumber::Launcher
484
686
  end
485
687
  end
486
688
 
689
+ # @!visibility private
487
690
  def ping_app
488
691
  url = URI.parse(ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/")
489
692
 
@@ -506,17 +709,19 @@ class Calabash::Cucumber::Launcher
506
709
  status
507
710
  end
508
711
 
712
+ # @!visibility private
509
713
  def stop
510
714
  RunLoop.stop(run_loop) if run_loop && run_loop[:pid]
511
715
  end
512
716
 
717
+ # @!visibility private
513
718
  def calabash_notify(world)
514
719
  if world.respond_to?(:on_launch)
515
720
  world.on_launch
516
721
  end
517
722
  end
518
723
 
519
-
724
+ # @!visibility private
520
725
  def info_plist_as_hash(plist_path)
521
726
  unless File.exist?(plist_path)
522
727
  raise "Unable to find Info.plist: #{plist_path}"
@@ -525,6 +730,7 @@ class Calabash::Cucumber::Launcher
525
730
  CFPropertyList.native_types(parsedplist.value)
526
731
  end
527
732
 
733
+ # @!visibility private
528
734
  def detect_bundle_id
529
735
  begin
530
736
  bundle_path = self.simulator_launcher.app_bundle_or_raise(app_path)
@@ -535,60 +741,91 @@ class Calabash::Cucumber::Launcher
535
741
  end
536
742
  end
537
743
 
744
+ # @!visibility private
538
745
  def calabash_no_stop?
539
746
  calabash_no_launch? or ENV['NO_STOP']=="1"
540
747
  end
541
748
 
749
+ # @!visibility private
542
750
  def calabash_no_launch?
543
751
  ENV['NO_LAUNCH']=='1'
544
752
  end
545
753
 
754
+ # @!visibility private
546
755
  def device_target?
547
756
  (ENV['DEVICE_TARGET'] != nil) && (not simulator_target?)
548
757
  end
549
758
 
759
+ # @!visibility private
550
760
  def simulator_target?(launch_args={})
551
761
  value = ENV['DEVICE_TARGET'] || launch_args[:device_target]
552
762
  return false if value.nil?
553
763
  value.downcase.include?('simulator')
554
764
  end
555
765
 
766
+ # @!visibility private
556
767
  def sdk_version
557
768
  ENV['SDK_VERSION']
558
769
  end
559
770
 
771
+ # @!visibility private
772
+ def sdk_version_for_simulator_target(launch_args)
773
+ return nil if device_target?
774
+ value = launch_args[:device_target]
775
+ return nil if value.nil?
776
+ return nil unless value.downcase.include?('simulator')
777
+ # we have a string like:
778
+ # iPhone Retina (4-inch) - Simulator - iOS 7.1
779
+ # iPad Retina - Simulator - iOS 6.1
780
+ # iPhone Retina (4-inch 64-bit) - Simulator - iOS 7.0
781
+ sdk = value.split(' ').last
782
+
783
+ # legacy support for DEVICE_TARGET=simulator
784
+ return nil if sdk == 'simulator'
785
+ sdk
786
+ end
787
+
788
+ # @!visibility private
560
789
  def use_instruments_env?
561
790
  ENV['LAUNCH_VIA'] == 'instruments'
562
791
  end
563
792
 
793
+ # @!visibility private
564
794
  def use_sim_launcher_env?
565
795
  ENV['LAUNCH_VIA'] == 'sim_launcher'
566
796
  end
567
797
 
798
+ # @!visibility private
568
799
  def reset_between_scenarios?
569
800
  ENV['RESET_BETWEEN_SCENARIOS']=="1"
570
801
  end
571
802
 
803
+ # @!visibility private
572
804
  def device_env
573
805
  ENV['DEVICE']
574
806
  end
575
807
 
808
+ # @!visibility private
576
809
  def app_path
577
810
  ENV['APP_BUNDLE_PATH'] || (defined?(APP_BUNDLE_PATH) && APP_BUNDLE_PATH) || ENV['APP']
578
811
  end
579
812
 
813
+ # @!visibility private
580
814
  def run_with_instruments?(args)
581
815
  args && args[:launch_method] == :instruments
582
816
  end
583
817
 
818
+ # @!visibility private
584
819
  def active?
585
820
  not run_loop.nil?
586
821
  end
587
822
 
823
+ # @!visibility private
588
824
  def instruments?
589
825
  !!(active? && run_loop[:pid])
590
826
  end
591
827
 
828
+ # @!visibility private
592
829
  def inspect
593
830
  msg = ["#{self.class}: Launch Method #{launch_args && launch_args[:launch_method]}"]
594
831
  if run_with_instruments?(self.launch_args) && self.run_loop
@@ -597,17 +834,19 @@ class Calabash::Cucumber::Launcher
597
834
  msg.join("\n")
598
835
  end
599
836
 
600
- # extracts server version from the app binary at +app_bundle_path+ by
837
+ # @!visibility private
838
+ # Extracts server version from the app binary at `app_bundle_path` by
601
839
  # inspecting the binary's strings table.
602
840
  #
603
- # SPECIAL: sets the +@@server_version+ class variable to cache the server
604
- # version because the server version will never change during runtime.
841
+ # @note
842
+ # SPECIAL: sets the `@@server_version` class variable to cache the server
843
+ # version because the server version will never change during runtime.
605
844
  #
606
845
  # @return [String] the server version
607
846
  # @param [String] app_bundle_path file path (usually) to the application bundle
608
- # @raise [RuntimeError] if there is no executable at +app_bundle_path+
847
+ # @raise [RuntimeError] if there is no executable at `app_bundle_path`
609
848
  # @raise [RuntimeError] if the server version cannot be extracted from any
610
- # binary at +app_bundle_path+
849
+ # binary at `app_bundle_path`
611
850
  def server_version_from_bundle(app_bundle_path)
612
851
  return @@server_version unless @@server_version.nil?
613
852
  exe_paths = []
@@ -665,6 +904,7 @@ class Calabash::Cucumber::Launcher
665
904
  # WIP: this is a proof-of-concept implementation and requires _strict_
666
905
  # equality. in the future we should allow minimum framework compatibility.
667
906
  #
907
+ # @!visibility private
668
908
  # @return [nil] nothing to return
669
909
  def check_server_gem_compatibility
670
910
  app_bundle_path = self.launch_args[:app]