calabash-cucumber 0.10.0.pre1 → 0.10.0.pre2

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 (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]